How to compare char* to string literal in C?

2 min read Original article ↗

Yes it will. However, your code is not comparing a char * to a string literal. It is comparing two string literals. The compiler is smart enough to spot this and optimize all the code away. Only the code inside the if block remains.

We can see this by looking at the assembly code generated by the comiler:

cc -S -std=c11 -pedantic -O3 test.c

First with your original code...

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

int main() {
    unsigned int len = 2;
    char * str = "OK";
    if (len == 2 && strncmp(str, "OK", len) == 0) {
      puts("Match");
    }
}

Then with just the puts.

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

int main() {
    //unsigned int len = 2;
    //char * str = "OK";
    //if (len == 2 && strncmp(str, "OK", len) == 0) {
      puts("Match");
    //}
}

The two assembly files are practically the same. No trace of the strings remains, only the puts.

    .section    __TEXT,__text,regular,pure_instructions
    .build_version macos, 10, 14    sdk_version 10, 14
    .globl  _main                   ## -- Begin function main
    .p2align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## %bb.0:
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register %rbp
    leaq    L_.str(%rip), %rdi
    callq   _puts
    xorl    %eax, %eax
    popq    %rbp
    retq
    .cfi_endproc
                                        ## -- End function
    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz  "Match"


.subsections_via_symbols

This is a poor place to focus on optimization. String comparison against small strings is very unlikely to be a performance problem.

Furthermore, your proposed optimization is likely slower. You need to get the length of the input string, and that requires walking the full length of the input string. Maybe you need that for other reasons, but its an increasing edge case.

Whereas strncmp can stop as soon as it sees unequal characters. And it definitely only has to read up to the end of the smallest string.