Вопрос

The title might be somewhat confusing, so I'll try to explain.

Is there a preprocessor directive that I can encapsulate a piece of code with, so that if this piece of code contains a compilation error, then some other piece of should be compiled instead?

Here is an example to illustrate my motivation:

#compile_if_ok
    int a = 5;
    a += 6;
    int b = 7;
    b += 8;
#else
    int a = 5;
    int b = 7;
    a += 6;
    b += 8;
#endif

The above example is not the problem I am dealing with, so please do not suggest specific solutions.

UPDATE:

Thank you for all the negative comments down there.

Here is the exact problem, perhaps someone with a little less negative approach will have an answer:

I'm trying to decide during compile-time whether some variable a is an array or a pointer.

I've figured I can use the fact that, unlike pointers, an array doesn't have an L-value.

So in essence, the following code would yield a compilation error for an array but not for a pointer:

int a[10];
a = (int*)5;

Can I somehow "leverage" this compilation error in order to determine that a is an array and not a pointer, without stopping the compilation process?

Thanks

Это было полезно?

Решение

No.

It's not uncommon for large C++ (and other-language) projects to have a "configuration" stage designed into their build system to attempt compilation of different snippets of code, generating a set of preprocessor definitions indicating which ones worked, so that the compilation of the project proper can then use the preprocessor definitions in #ifdef/#else/#endif statements to select between alternatives. For many UNIX/Linux software packages, running the "./configure" script coordinates this. You can read about the autoconf tool that helps create such scripts at http://www.gnu.org/software/autoconf/

Другие советы

This is not supported in standard C. However, many command shells make this fairly simple. For example, in bash, you can write a script such as:

#!/bin/bash

# Try to compile the program with Code0 defined.    
if cc -o program -DCode0= "$*"; then
    # That worked, do nothing extra. (Need some command here due to bash syntax.)
    /bin/true
else
    # The first compilation failed, try without Code0 defined.
    cc -o program "$*"
fi

./program

Then your source code can test whether Code0 is defined:

#if defined Code0
    foo bar;
#else
    #include <stdio.h>
    int main(void)
    {
        printf("Hello, world.\n");
        return 0;
    }
#endif

However, there are usually better ways to, in effect, make source code responsive to the environment or the target platform.

On the updated question :

If you're writing C++, use templates...

Specifically, to test the type of a variable you have helpers : std::enable_if, std::is_same, std::is_pointer, etc

See the type support module : http://en.cppreference.com/w/cpp/types

C11 _Generic macros might be able to handle this. If not, though, you're screwed in C.

Not in the C++ preprocessor. In C++ you can easily use overload resolution or a template or even expression SFINAE or anything like that to execute a different function depending on if a is an array or not. That is still occurring after preprocessing though.

If you need one that is both valid C and valid C++, the best you can do is #ifdef __cplusplus and handle it that way. Their common subset (which is mostly C89) definitely does not have something that can handle this at any stage of compilation.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top