CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

CCS 5.026 - strcmp / strncmp returns 255 [SOLVED]

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

CCS 5.026 - strcmp / strncmp returns 255 [SOLVED]
PostPosted: Fri Feb 16, 2018 2:30 pm     Reply with quote

Device: PIC24EP512GP806
Compiler: 5.026 w/ 5.071 IDE

Hello all,

I've noticed that strcmp and strcnmp on some particular situations don't return "result is -1 (less than), 0 (equal) or 1 (greater than)" like the manual states and like it should.

At the moment, I am comparing two strings and regardless if I use strcmp or strncmp, they both return 255.

I realize the strings aren't the same but I'd expect to have -1, 0 or 1 depending on the comparison. This screws-up my code big times. I don't understand because the function is used many other places in the code and this one particular place, fail.

This code worked up to like *now* without me changing anything in that area. I changed the data in the strings and stuff but not the function which worked for the last era.

Thanks.

Any idea?

Ben


Last edited by benoitstjean on Mon Feb 19, 2018 1:37 pm; edited 1 time in total
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 2:43 pm     Reply with quote

Get this.... so inverting the strings in the function now returns the correct value.

It is **similar** to the idea below... I have two global variables, one of them is known (string1) and the other is filled in the function. String1 gets passed to the function. Insinde the function, string2 is filled and compared with string1 filled outside the function.
Code:

// Global variable
unsigned char string1[10] = "MyString1";
unsigned char string2[10] = "";

MyFunction( string1 );

void MyFunction( unsigned char *FuncString )
{
    int8 RetVal;

   sprintf( string2, "MyString2" );

   RetVal = strncmp( FuncString, MyString1 );

   --> FAIL: RetVal returns 255

   RetVal = strncmp( MyString1, FuncString );

   --> SUCCESS: RetVal returns 1

}

Why does swapping the strings works??

Ben
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 2:57 pm     Reply with quote

OK, I don't use them 24 PICs but... can you roll back the compiler version and test ? Maybe 'something' changed in the compiler..one of those 'fixed A, broke B' situations.

I was thinking about variable default types... but if it worked 'last week', that shouldn't be the problem unless....CCS changed something...

sigh...I really hate stuff like this now..the 'used to work' problem
hopefully someone familair with 24s will chime in soon
At least it's sunny here in Ontario !
Jay
gaugeguy



Joined: 05 Apr 2011
Posts: 286

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:11 pm     Reply with quote

If you want a signed return (-1, 0, 1) then you need to make sure your variable is signed.
A signed int8 cannot hold 255. It can only hold -128 - 127.
An unsigned in8 value of 255 is stored the same as a signed int8 value of -1.
The problem may be either how the variable is declared or how the value in the variable is being viewed.
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:38 pm     Reply with quote

To Gaugeguy:

I'm comparing strings and they are all declared as <unsigned char> so this is basically 0-255.


To Temtronic:

It's not a compiler thing, I mean, I've used the same 'everything' for ages.

Yes, I *did* change *some* code over the last few days but it's not code that should have affected how strncmp works. I mean, a string is a string. I'm comparing two strings of 9 bytes + end-of-string NULL (strings are 10-bytes long).


Note regarding my previous "ah-ha!" moment: It's still not working and this time, it's always returning 1.

The funny thing is that it doesn't make any sense that swapping the same strings yields different results... 1 vs 255?? I would have expected 1, -1 or 0... but not 1 then 255.

I know that it will be something very stupid when I realize what it is... but I've encountered this problem in the past and was not able to figure-out what it was and the problem disappeared all of a sudden.

I'll post results when I find something but in the meantime, any ideas are welcomed.

Thanks guys.

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:46 pm     Reply with quote

The point is the return from the function is a signed value.
If you are putting it into an unsigned value, you will see 255, for the -1 return.
So you get -1 and 1 as the two returns (A<B or A>B), when you reverse the strings.

Try a little test:
Code:

   int8 Retval;
   signed int8 gtr=1, less=-1;

   Retval=gtr; //What is Retval?.
   Retval=less; //what is Retval?.
temtronic



Joined: 01 Jul 2010
Posts: 9081
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:51 pm     Reply with quote

hmm any chance 255 is the undocumented result from comparing when 1 string has zero length ?
in you ah-ha string2 has zero characters in it.

yeah, I know pulling at straws....it's just that '255' is unique or special.
hopefully you'll still have some hair left when you discover the reason.

I still ahve no idea where Windows 'put' 20,000+ PIC files....

Jay
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:52 pm     Reply with quote

Quote:

void MyFunction( unsigned char *FuncString )
{
int8 RetVal;

sprintf( string2, "MyString2" );

RetVal = strncmp( FuncString, MyString1 );
RetVal = strncmp( MyString1, FuncString );

}

How do you get this to compile ? If I try to compile it, I get these errors:
Quote:
*** Error 102 "PCH_Test.c" Line 21(34,41): Expect comma
*** Error 102 "PCH_Test.c" Line 27(31,41): Expect comma

The CCS manual says that strncmp() has a 3rd parameter, which is the
number of bytes to compare:
Quote:
iresult=strncmp (s1, s2, n) // Compare s1 to s2 (n bytes)

You're missing the byte count.
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 3:53 pm     Reply with quote

BOOM. Nailed it.

And I mis-read / mis-understood gaugeguy's explanation. I thought *somehow* he was referring to the strings in the function as opposed to the returned code. So his explanation was right.

I'll confirm this monday but it all makes sense. Yes, I am declaring the returned value for the strncmp as unsigned int8 rather than int8.

Doesn't explain why the code always worked up until now but anyhow, monday I will test all of this.

Arghhh.... Hey, it's friday...

Thanks all.

Ben
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Fri Feb 16, 2018 4:28 pm     Reply with quote

Tp PCM programmer:

My mistake, I wrote the code in this forum as if I was "programming", it's not an excerpt from my code. Yes, there should have been a length value as third parameter.

Anyhow, I strongly believe that the problem is what TTelmah and Gaugeguy have said - I am storing the returned value in an unsigned int8 rather than an int8.

Will confirm monday.

Thanks all.

Ben
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 8:58 am     Reply with quote

All right, results are in...

This is pretty much what my code does except I changed the variable names to make it easy to read and understand and I stripped the irrelevant stuff from the function.

Global variables:
Code:

unsigned char *S1;
unsigned char *S2;
unsigned char *L1;
unsigned char *L2;

L1 and L2 are loaded from an EEPROM. These don't change.
S1 and S2 change based on events.

S1 and S2 get passed to the function:

Code:
IsDataValid( 0, S1, S2 );


bool IsDataValid( unsigned int8 ID, unsigned char *TestS1, unsigned char *TestS2 )
{
   int8 Top     = 0;
   int8 Left    = 0;

   int8 Bottom  = 0;
   int8 Right   = 0;

   Top    = strcmp( L1, TestS1 );
   Left   = strcmp( L2, TestS2 );

   Bottom = strcmp( L1, TestS1 );
   Right  = strcmp( L2, TestS2 );

   // Check some stuff here and return TRUE or FALSE
}

In the above test, strcmp returns 255. Swapping the strings from the function, strcmp always returns 1.

There are some instances where I *know* that strcmp should return -1 or 0 but it's always 1 or 255.

Still investigating... really does not make sense.

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19195

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 10:02 am     Reply with quote

It makes total sense, depending on how you are testing 'strcmp returns 255'.
Whatever you are putting it into to test, is being told to display the value as an unsigned int8.
For instance:
Code:

   int8 fred=-1; //fred is now a signed int8

   printf("%3u\n", fred); //prints 255
   printf("%3d\n",fred); //printf -1


C, and debuggers will 'believe what you tell them' about the size and type of variables. Somewhere something in your code or debugger settings is treating the variable as unsigned.
For instance if you have #type UNSIGNED, then an 'int8' will be unsigned. Or if (as a I show), you treat the variable as unsigned (passing it to something that only accepts an unsigned value), it'll be treated as 255.
If you have your debugger setup to assume unsigned, then it'll display the byte as 255.
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 10:32 am     Reply with quote

Yeah, I realized that like a minute ago that I was printing using %u rather than %d...

It's monday morning...

Ben
benoitstjean



Joined: 30 Oct 2007
Posts: 542
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Mon Feb 19, 2018 1:37 pm     Reply with quote

There were a few other things in my code but wrong returned value was my fault because I was using an unsigned int8.

I really missed that one.

Thanks all.

Ben
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group