Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7942 Discussions

FE_INVALID is zero to pre-processor

tydeman
Beginner
669 Views
The following code fails icc 11.1 since the preprocessor thinks
the FE_* macros are zero, when then are non-zero at runtime.

#include
#ifdef FE_INVALID
#if FE_INVALID
/* Non-zero => OK */
#else
#error FE_INVALID defined as zero (enum is non-zero)
#endif
#else
#error FE_INVALID not defined
#endif

0 Kudos
7 Replies
Milind_Kulkarni__Int
New Contributor II
669 Views
This is not a bug in Intel or any compilers which behave the same, but a usually overlooked behaviour of enums vs #define behaviour.

enum's are not considered by preprocessor, as they are not defines, and you are using enum's with defines.

Try creating a spearate user header file, and try this by defining you own enum, and checking in your main program.
0 Kudos
Milind_Kulkarni__Int
New Contributor II
669 Views
A very good example is shown in this link:-- http://discuss.joelonsoftware.com/default.asp?design.4.28018.14

Though I am also surprised how enum's in this case work with #ifdef while they do not work with #if , and same for gcc , can you try any other compiler/preprocessor that can give different behaviour with either #if or #ifdef or both , for the enum's.

Perhaps, its a part of ANSI C standard, or left to preprocessor-dependent implementation.

0 Kudos
Milind_Kulkarni__Int
New Contributor II
669 Views

The following small test-code provides more clarity.

[bash]int FE=1;
int main()
{

#ifdef FE
printf("%dn", FE);
#endif

#if FE
printf("%dn", FE);
#endif
return 1;
}

[/bash]
0 Kudos
tydeman
Beginner
669 Views
Intel's (and gcc's) is violating the C standard with their implementation
of the FE_* macros mixed with enums.

C99: 7.6 Floating-point environment
Paragraph 5: The defined macros expand to integer constant expressions
with values such that bitwise ORs of all combinations of the macros result
in distinct values.

So, given your implementation, this code shows a direct violation of the above.

#if (FE_INVALID|FE_DIVBYZERO) == (FE_OVERFLOW|FE_UNDERFLOW)
#error Violation of C99
#endif

The use of enums and #defines in your header is not the way to met conformance to C99.
0 Kudos
Milind_Kulkarni__Int
New Contributor II
669 Views
Only 1 thing I left in my sample piece of code:--

int FE=1
#define FE FE /// this is similar to what the fenv.h defines, rest all same in test-code.

As for your argument, you are right. The #if does not work for the case, and would throw error, when it should have not. But, so far even the excerpt from the C99 Para 5 does not allow or justify the #if use case , as you have shown here.

Perhaps you missed Para 6 of the standard, which says:-- (and this is implemented in the )

#define FE_ALL_EXCEPT \

(FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID)

Perhaps these flags are just useful for checking floating-point status flags during runtime arithmetic of floating-point flags when exceptions are raised during function call and floating arithmetic etc.

The use case that you have provided probably does not help too much practically when the program is in execution in memory.

0 Kudos
Milind_Kulkarni__Int
New Contributor II
669 Views
The point of my saying is :-- "For the preprocessor, it just matters whether those MACROS are defined or NOT, and not the values", while "in runtime, the values also matter".

And that is why in , ther are implemented both as a Macro, as well as an Enum to support my above statement..

So #ifdef works, and not #if .

Please let me know whether anything is clear in the jumble of words :)
0 Kudos
Milind_Kulkarni__Int
New Contributor II
669 Views
Probably, the smart mixing of enum's and macros is done here to let compiler know that if these are defined, then setting the appropriate floating-point environment.

But, as Macros come with their own set of disadvantages like no type-checking , among others, and they needed to propagate the use to run-time exceptions and Status flags, they had to put it as data-type.

#if not gettingevaluated could be a side-effect of this uncommon mixing , rather than the "lack of need" for it.
0 Kudos
Reply