1

I have larger C code base, where I want to integrate some C++ code. The C++ code needs some declarations from the C code base.

Compiler is currently GCC 6.3.1, but we might be able to update the compiler.

Basically, the included C headers contain code like this:

#define NRF_GPIO  ((int*)          0x0000112233)
static_assert(NRF_GPIO == NRF_GPIO, "asd");

This compiles fine, if the compiler compiles C files, but fails, if the code is written in C++, as the reinterpret cast will not yield in a constant expression and the compiler correctly complains about it:

error: non-constant condition for static assertion
 static_assert(NRF_GPIO == NRF_GPIO, "asd");
                        ^
t.cpp:2:20: error: reinterpret_cast from integer to pointer
 #define NRF_GPIO  ((int*)          0x0000112233)
                   ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t.cpp:3:15: note: in expansion of macro 'NRF_GPIO'
 static_assert(NRF_GPIO == NRF_GPIO, "asd");

Is there a way to let the GCC compile the C++ a little bit more relaxed and thus to except the code above?

6
  • 2
    I guess your real code doesn't check that a preprocessor symbol is equal to itself. If you would show a real example it might be easier to propose a workaround. Can you use two macros, e.g. #define NRF_GPIO_ADDR 0x0000112233 and #define NRF_GPIO ((int*) NRF_GPIO_ADDR) and use NRF_GPIO_ADDR for the assertion? Commented Mar 22, 2023 at 17:30
  • 2
    If you have a C header that you cannot use with C++ code, you need to make a separate C++ header (or tell the creator of the C header to add some #ifndef __cplusplus to make it a C/C++ header) Commented Mar 22, 2023 at 17:33
  • @Bodo Of cause, the real, failing assert does some more magic, but in the end, it really boils down to the given example. If I could tell gcc to have this assert in C++ the same as it handles it in C, my problem would have been solved. Commented Mar 22, 2023 at 17:38
  • @Artyer well duplicated code is not really an option and I want to change the existing C code as little as possible (preferable, I don't want to change the code at all). Commented Mar 22, 2023 at 17:38
  • @TorstenRobitzki If it boils down to the example, then the condition will always be true and there's no need for a static_assert. Commented Mar 22, 2023 at 17:57

1 Answer 1

4

It is not guaranteed to work in C either. In C the static assertion requires an integer constant expression, which may contain casts to non-integer types only as part of sizeof or _Alignof operands.

C does permit an implementation to allow other forms of constant expressions, but at least with the current C23 working draft it has been clarified that this does not affect the validity as integer constant expression. See N2713.

GCC also warns about that with -pedantic.

You generally can't invent out-of-thin-air pointer values and use them at compile time in C++ (except for null pointer values). C allows slightly more, but not in contexts requiring integer constant expressions. See below.

The only way to work with this is to keep the address as a numeric value at compile-time and convert it to a pointer only at runtime when it is needed as such.

There is one exception in C, but not C++: An integer constant can be cast to a pointer and be used as an address constant to constant-initialize a variable. However even then the address constant cannot be an operand to == (or most other operators) in the initializer expression, nor is it allowed in an integer constant expression.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, this would also explain, why the C example fails to compile with a newer version of clang.
C recognizes NRF_GPIO as constant address. See 6.6p9 "integer constant cast to pointer type". Still comparison of those two is not "arithmetic constant expression".
@tstanisl My understanding is that this is only relevant to constant-initialization of variables, not _Static_assert, but it is really a minor difference to C++. In C++ such an address constant cast from an integer constant would not be considered a constant expression and may therefore have dynamic initialization. I have mentioned it in the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.