On 15/02/2023 15:27, Richard Earnshaw wrote: > > > On 15/02/2023 15:10, Jonny Grant wrote: >> Thank you for your quick reply Richard. >> >> On 15/02/2023 14:30, Richard Earnshaw wrote: >>> >>> >>> On 15/02/2023 14:18, Jonny Grant wrote: >>>> Hi >>>> Has GCC considered an improvement to "compile out" from the builtin printf the strings? That being to change it to just be something like puts("file /app/example.cpp:4") >>>> I had a look, but couldn't find it being asked before. >>>> >>>> This is just a short example to demonstrate. >>>> It would be useful to see the exact string in the debugger "file /app/example.cpp:4", also it saves a few lines of asm. >>>> >>>> https://godbolt.org/z/aKz3o6aPd >>>> >>>> >>>> int main() >>>> { >>>> __builtin_printf("file %s:%d", __FILE__, __LINE__); >>>> } >>>> >>>> >>>> .LC0: >>>> .string "/app/example.cpp" >>>> .LC1: >>>> .string "file %s:%d" >>>> main: >>>> subq $8, %rsp >>>> movl $4, %edx >>>> movl $.LC0, %esi >>>> xorl %eax, %eax >>>> movl $.LC1, %edi >>>> call printf >>>> xorl %eax, %eax >>>> addq $8, %rsp >>>> ret >>> >>> We already do when the printf contains simply the format string and no additional arguments. >>> >>> I guess it might be possible to handle cases where all the arguments are constant, but even that has its problems, eg: >>> >>> - can we guarantee identical output to the platform printf? >> >> That's a good question. I was using __builtin_printf so that should be GCC I expect. >> > > No, __builtin_printf is really just an internal hook that is used to handle optimisations of printf - if you look at your assembly output you'll see it is translated back to printf for the C library to handle. ok I see. I changed the example to take off the end "\n" and it goes back to printf (otherwise it is puts() ) https://godbolt.org/z/W46esaWKd > >>> - does it cause string bloat (what if there were 30 or so such statements in your program all identical except for the line number)? >> >> That's probably what I am expecting, to see those 30 different formatted strings. >> >>> - does it even happen often enough to be worth adding (and maintaining) support? Nothing comes for free in a compiler and the optimisations have to be worth-while in the real world. >>> >>> R. >> >> You're completely right, it could bloat the file with strings. >> >> I can do some with multi-line literals, to get "file /app/example.cpp compiled Feb 15 2023" >> __FILE__ and __DATE__ worked ok. >> >> but it didn't like me putting __PRETTY_FUNCTION__ in the middle. Maybe I'm missing something obvious. Likewise I can't use __builtin_LINE() as that is a function rather than a string. Maybe __PRETTY_FUNCTION__ and __FUNCTION__ are calls to __builtin_FUNCTION(). >> >> int main() >> { >> const char * s = "file " \ >> __FILE__ \ >> " compiled " \ >> __DATE__ \ >> "\n"; >> >> __builtin_printf("%s", s); >> __builtin_printf("%s\n", __PRETTY_FUNCTION__); // didn't work when I put in the middle. >> > > That's because __func__, __FUNCTION__ and __PRETTY_FUNCTION__ are not string literals but implicitly declared identifies containing a constant string literal as the initializer - you can't therefore combine them with string literals by simple concatenation. See > > https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html > > which clearly states this. > Ok, thank you for the link, I understand it wouldn't support simple concatenation of __func__ etc the way __DATE__ works. I remembered I could convert macro arguments in into a string constant. So could get the __LINE__ which is enough with the file name into one string with GCC. #define xto_str(s) to_str(s) #define to_str(s) #s int main() { const char * s = __FILE__ ":" xto_str(__LINE__); __builtin_printf(s); } .LC0: .string "/app/example.cpp:6" main: subq $8, %rsp movl $.LC0, %edi xorl %eax, %eax call printf xorl %eax, %eax addq $8, %rsp ret