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