GCC compile time string comparison

David Brown david@westcontrol.com
Thu Aug 18 13:15:00 GMT 2011


On 18/08/2011 14:10, Pintu Agarwal wrote:
> Hi,
>
> Thanks for yoru reply.
>
> I got some reference from http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
>            #define Scale_Value(X)      \
>              (__builtin_constant_p (X) \
>              ? ((X) * SCALE + OFFSET) : Scale (X))
> Here it says that builtin function can be used inside macro.

You are missing the point.

Of course you can put builtin functions inside a macro - you can put 
anything you like inside a macro, as long as it expands to valid C code.

But you /cannot/ put anything you like inside a pre-processor 
conditional line (an "#if" line).  You can only use things that can be 
evaluated by the pre-processor, which basically means simple arithmetic 
using constants (or #define'd constants).  Functions - builtin or normal 
functions - are C concepts, while the pre-processor is a simple text 
macro processor.

Very often, the compiler can evaluate builtin functions (and other 
functions, if it knows the definition at compile-time) at compile time, 
if the arguments are all constants and optimisation is enabled.  For 
example, you can use this code:

#define STRCMP(s1,s2)       __builtin_strcmp(s1,s2)
int main()
{
	if (STRCMP("pintu1","pintu2")) {
		printf("Equal...\n");
	} else {
		printf("Not Equal...\n");
	}
	return 0;
}

When compiled, gcc will figure out the result of strcmp at compile time, 
giving a result less than 0 (you do know that strcmp() gives 0 if the 
strings are the same?).  It then notes that the condition for the if() 
is known to be constant non-zero, and can eliminate the entire test and 
the "printf("Not Equal...")" statement - giving exactly the code you 
would have got if the pre-processor worked the way you apparently hoped 
it did.

You also don't have to use __builtin_strcmp - just use normal strcmp, 
and let the compiler choose when to use the builtin version and when to 
call the library version.

There was a time when compilers were poor, and it made sense to do magic 
with the pre-processor.  These days you are normally much better off 
writing the code in proper C and letting the compiler generate optimal code.

mvh.,

David



>
> But the folowing sample code does not work for me.
> --------------------------------------------------------------------------------
> #define CONFIG_DUAL_MODE        1
> #define CHECK(X)        (__builtin_constant_p (X) \
>                          ? (1) : (0))
>
> int main()
> {
>
>          #if CHECK(CONFIG_DUAL_MODE)
>                  printf("Equal...\n");
>          #else
>                  printf("Not Equal...\n");
>          #endif
>
>
>          return 0;
> }
> #gcc -o testmacro.out testmacro.c
> ERROR :  error: missing binary operator before token "("
> --------------------------------------------------------------------------------------
> Please help me to fix this.
>
>
>
> Thanks,
> Pintu
>
>
>
> On Thu, Aug 18, 2011 at 4:29 PM, Jonathan Wakely<jwakely.gcc@gmail.com>  wrote:
>>
>> On 18 August 2011 11:52, Pintu Agarwal wrote:
>>> Hi,
>>>
>>> I wanted to do compile time string const comparison in a macro call
>>> but I could not find anything in GCC.
>>>
>>> I tried using __builtin_ extended option but it is not working inside a macro.
>>> Here is the sample code:
>>>
>>> #define STRCMP(s1,s2)       __builtin_strcmp(s1,s2)
>>>
>>> int main()
>>> {
>>>         #if STRCMP("pintu1","pintu2")
>>>                 printf("Equal...\n");
>>>         #else
>>>                 printf("Not Equal...\n");
>>>         #endif
>>>
>>>         return 0;
>>> }
>>>
>>> But I am getting this error : error: missing binary operator before token "("
>>>
>>> I tried other option such as __builtin_expect, __builtin_constant_p
>>> etc but same problem when used inside macro call
>>
>> The preprocessor can only expand macros and perform simple arithmetic
>> on constant expressions, it can't call functions. That includes
>> builtin functions.
>>
>> Compile-time string comparison is just about possible by abusing C++
>> templates, but you probably don't want to go there.
>




More information about the Gcc-help mailing list