UPDATE 2
Per your request, I will unequivocally state there is no part of the standard that allows you to obtain the length of a constant string except through the use of functions like strlen
. You won't be able to create a macro that can do what you want.
You wrote:
strlen is runtime call
It can be a run-time call or a compile-time call depending upon the compiler's optimization level, which, so far, no other person has mentioned. I'm a huge fan of letting the compiler do the work for me.
$ cat t.c
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[]) {
char *data[] = {"abc"};
printf("sl=%ld\n", strlen(data[0]));
}
$ gcc t.c
$ nm a.out
U ___stack_chk_fail
U ___stack_chk_guard
0000000100008018 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100003f00 T _main
U _printf
U _strlen
U dyld_stub_binder
$ gcc -O1 t.c
$ nm a.out
0000000100008008 d __dyld_private
0000000100000000 T __mh_execute_header
0000000100003f70 T _main
U _printf
U dyld_stub_binder
UPDATE 1, prompted by chqrlie. See the instruction at 100003f7b. Altering the number of characters in that string will produce a different constant being loaded into the esi register.
$ objdump --disassemble-symbols=_main a.out
a.out: file format mach-o 64-bit x86-64
Disassembly of section __TEXT,__text:
0000000100003f70 <_main>:
100003f70: 55 pushq %rbp
100003f71: 48 89 e5 movq %rsp, %rbp
100003f74: 48 8d 3d 33 00 00 00 leaq 51(%rip), %rdi # 100003fae <dyld_stub_binder+0x100003fae>
100003f7b: be 03 00 00 00 movl $3, %esi #### This is the length of the string constant
100003f80: 31 c0 xorl %eax, %eax
100003f82: e8 05 00 00 00 callq 0x100003f8c <dyld_stub_binder+0x100003f8c>
100003f87: 31 c0 xorl %eax, %eax
100003f89: 5d popq %rbp
100003f8a: c3 retq
But even if it is a run-time call, there are two things to remember:
- The cost of an optimized
strlen
call is quite small compared to many other operations that you would probably perform on the string.
- You can minimize the frequency of your calls to
strlen
with responsible factoring.