4

I have following function to compare two char arrays in C:

short test(char buffer[], char word[], int length) {
    int i;
    for(i = 0; i < length; i++) {
        if(buffer[i] != word[i]) {
            return 0;
        }
    }
    return 1;
}

And somewhere in main:

char buffer[5]; //which is filled correctly later
...
test(buffer, "WORD", 5);

It returns 0 immediately at i = 0. If I change function to this:

short test(char buffer[], int length) {
    int i;
    char word[5] = "WORD";
    for(i = 0; i < length; i++) {
        if(buffer[i] != word[i]) {
            return 0;
        }
    }
    return 1;
}

... it works like a charm. In the first version of function test debugger says that buffer and word arrays are type of char*. In the second version of function test it says that the buffer is type of char* and the test array is type of char[]. Function strcmp() does not work neither.

What is actually wrong here? Program is made for PIC microcontroller, compiler is C18 and IDE is MPLAB.

13
  • you pass in word[] and then use ukaz[] ??? Commented Nov 24, 2013 at 0:04
  • sorry where is ukaz coming from? Commented Nov 24, 2013 at 0:04
  • Woops ... forgot to translate that! Corrected now. @MitchWheat Commented Nov 24, 2013 at 0:05
  • @drive235 You say buffer is filled in correctly but I'm skeptical. Also, in the second example you declare word as an array of 5 chars and then initialize it with 6 chars. I don't know what your compiler does with that but it's not how you should do it. You don't need to add \0 to a literal string in C unless that string requires double null termination. Commented Nov 24, 2013 at 0:10
  • 2
    I assume you know it returns 0 right away, because you put a printf() there or something to see that. Why not take a look at what buffer[0] and word[0] are? Might be the clue you're looking for. Commented Nov 24, 2013 at 0:11

1 Answer 1

4

Hmm...

Sometimes in embedded systems there is difference where strings are stored.

In the first example you define a string which is stored in flash code region only. So the comparison will fail with index 0 because of the memory area difference.

The second example you define a local variable which contain the same string. This will be located in RAM, so the comparison works since they are both in RAM.

I would test following:

char buffer[5]; //which is filled correctly later
char word[5] = "WORD";
...
test(buffer, word, 5);

Most likely it is going to work because the comparison is done in RAM totally.

Yes and remove the \0 since the "WORD" will null terminate automatically.

Sign up to request clarification or add additional context in comments.

3 Comments

Man, you saved the day (night). Thank you!
Good. It goes down to fact that PIC assembly is not able to do comparison between flash and ram. And those small device compilers are not good enough to handle the situation. Same thing happens sometimes with Keil and SDCC
As has been noted this is related to the PIC18 having a Harvard architecture with separate address spaces and instructions for accessing data in FLASH and variables in RAM. The standard libraries does supply a set of alternate string functions for dealing with FLASH pointers, in this case you want to try strncmppgm2ram(buffer, "WORD", length). Sidenote: MCC18 is a stupefyingly horrendous compiler, far beyond anything else I have ever encountered anywhere. If you value your sanity please switch to XC18 instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.