-3

I noticed that comparing a normal string variable with a string using strcmp and == operator both works, but comparing argv string using == doesn't works, only it works with strcmp. why? What is so special?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char const *argv[]) {
    char *tempStr = "string";
    int x = atoi(argv[2]), y = atoi(argv[3]);
    
    if (strcmp(tempStr, "string") == 0) {
        printf("'strcmp' methods works in case comparing with normal string variable\n");
    }
    if (tempStr == "string") {
        printf("'strcmp' as well as '==', both the methods works in case comparing with normal string variable\n");
    }
    

    /* this works for argv[] strings*/
    if (strcmp(argv[1], "add") == 0) printf("%d", x + y);
    else if (strcmp(argv[1], "subtract") == 0) printf("%d", x - y);
    else if (strcmp(argv[1], "multiply") == 0) printf("%d", x * y);
    else if (strcmp(argv[1], "divide") == 0) printf("%d", x / y);
    
    // /* this doesn't works for argv[] strings */ 
    // if (argv[1] == "add") printf("%d", x + y);
    // else if (argv[1] == "subtract") printf("%d", x - y);
    // else if (argv[1] == "multiply") printf("%d", x * y);
    // else if (argv[1] == "divide") printf("%d", x / y);

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Satyam S
  • 31
  • 6
  • 3
    There's nothing special about `argv`. You always use `strcmp()` to compare strings, not `==`. – Barmar Jul 27 '22 at 18:24
  • The only reason it works with `tempStr` is because it's a pointer to the same string literal. The compiler used the same memory for both of them, so the addresses are equal. It wouldn't work if you did `char tempStr[] = "string";` – Barmar Jul 27 '22 at 18:25

2 Answers2

2

When you use ==, it compares the addresses, not the contents. You declared tempStr as a pointer to a string literal, and compared it to the same string literal. The compiler noticed that the literals are the same, so it used the same memory for both of them, and that made the addresses the same.

You can't count on this being true, it's a compiler optimization to combine these similar strings.

If you change the declaration to

char tempStr[] = "string";

you would not get the same result with ==. In this case, tempStr is a local array, while "string" is a static string literal, and they will be in different memory locations.

Barmar
  • 741,623
  • 53
  • 500
  • 612
1

This comparison

char *tempStr = "string";
//...
if (tempStr == "string") {
    printf("'strcmp' as well as '==', both the methods works in case comparing with normal string variable\n");
}

can evaluate either to logical true or to logical false depending on the compiler option that determines whether identical string literals are stored by the compiler as one string literal (character array) or as separate character arrays.

As for this comparison

if (argv[1] == "add") printf("%d", x + y);

then as there are compared two pointers to strings that occupy different extents of memory then such a comparison always evaluates to logical false.

That is in the above comparison array designators are implicitly converted to pointers to first elements of the arrays and the pointers are compared.

The above if statement is equivalent to the following if statement

if ( &argv[1][0] == &"add"[0] ) printf("%d", x + y);
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335