ARM...ing your madness!!!

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello. I am not sure if I do something wrong but I am getting crazy!

 

I have the following 'binary' search in an array (screenshot bellow):

 

If you see, I compare with the strcmp function two different strings. One is the "WC," and the other the "WV,". You can see the variable values on the 'Watch' window also.

 

The result instead of being anything other than 0 (zero), it is zero!!!!!!!!! (see the 'val' variable on the watch window)

It is like comparing single characters !!!

 

Could please someone let me know what I do wrong? (if I do so).

 

This topic has a solution.
Last Edited: Fri. May 25, 2018 - 12:09 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally I found it!!!

strcmp returns an int and not int8_t.

Comparing the strings, the result is -4864. This number is exact multiple of 256 (with remainder of division, 0), which means that if you try to store it in a byte, the result is 0!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't believe you. strcmp() subtracts one letter out of the string from the corresponding letter in the other string.
It stops when it gets to non-zero or the NUL .
So the 1st comparison would be W-W, 2nd is C-V which is -19
.
It looks like you are using C++. You still need to include the C string.h header file because strcmp is a C library function.
In practice, you never use the actual numerical return value from strcmp. Just whether it is -ve, zero, +ve.
.
David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After opening my mouth,   I thought that I should test it.

void setup(void)
{
    Serial.begin(9600);
    int ret;
    ret = strcmp("WC", "WV");
    Serial.println(ret);
    ret = strcmp("WV", "WC");
    Serial.println(ret);
}

void loop(void)
{

}

And the result is:

-1
1

So strcmp() as used in C Standard Library by Arduino Uno and Arduino STM32F103 both return -1 and +1 for match failures.

Obviously some implementations return the specific -difference or +difference.    Your app only considers -ve, zero and +ve so it does not matter.

 

I know that Arduino pulls in the C string.h header file.

Do you specifically include string.h ?

 

Incidentally,  it is perfectly legal to assign an int to an int8_t variable.

I would expect a truncated -1 to still be -1 in an int8_t even if the function declaration was omitted.

It is not so straightforward with +1  or +value.    Especially with an omitted declaration.

 

David.

Last Edited: Fri. May 25, 2018 - 03:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry for my really late reply.

Yes. I am using C++. Based on your sayings (C-V = -19), this -19 if you multiply it with 256, it gives you the result I was getting (-4864).

Obviously it has to do with the implementation of the strcmp! I don't know why on your Arduino the results are -1, 0 or 1 but an implementation I found on internet is like the following:

int strcmp(const char* s1, const char* s2)
{
    while(*s1 && (*s1==*s2))
        s1++,s2++;
    return *(const unsigned char*)s1-*(const unsigned char*)s2;
}

You can check it at http://clc-wiki.net/wiki/C_standard_library:string.h:strcmp

 

I think that the char is 2 bytes on the ARM SAMD20 and due to the little endiannes (well... I totally guess here), the casting to int might result to -4864 instead of -19 (I am not quite sure I understand the last line)?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

strcmp() returns an int. It is not specified whether it is 1 or -1. Just positive or negative. ( or zero )
.
Your implementation will subtract the two uint8_t values. And sign extend the result to int32_t
.
An uint8_t is always 8 bits. And unsigned char is always uint8_t as far as I know.
If you want a wide character you should specifically say so. And write a specific function.
.
David.