Does not build for strict C99 #339

Open
opened 2021-04-14 04:51:04 -05:00 by miniwinwm · 10 comments
miniwinwm commented 2021-04-14 04:51:04 -05:00 (Migrated from github.com)

If compiler option -std=c99 is added the build fails because of some inline assembly instructions. While this is not a major problem, some projects require it.

If compiler option -std=c99 is added the build fails because of some inline assembly instructions. While this is not a major problem, some projects require it.
kilograham commented 2021-04-15 15:41:12 -05:00 (Migrated from github.com)

Helpful if you give build output; also how you chose to add -std=c99

Helpful if you give build output; also how you chose to add -std=c99
miniwinwm commented 2021-04-16 04:02:57 -05:00 (Migrated from github.com)

In my project I added the -std=c99 compiler flag in CMakeCache.txt, after running cmake, like this...

//Flags used by the C compiler during all build types.
CMAKE_C_FLAGS:STRING=-mcpu=cortex-m0plus -mthumb -std=c99

This line...

#include "pico/stdlib.h"

eventually includes platform.h, and it's this code that causes the error...

inline static int32_t __mul_instruction(int32_t a, int32_t b) {
asm ("mul %0, %1" : "+l" (a) : "l" (b) : );
return a;

The errors are first it thinks asm is a function and complains about an implicit declaration, then it barfs on the : in the middle as it's not C.

I have tried reproducing it using the standard examples, for example blink.c. I made the same change to pico-examples/build/CMakeCache.txt, but the blink project built without error so somehow the -std=c99 compiler flags I made is not getting transmitted through the examples build process.

My cmake file is unremarkable...

cmake_minimum_required(VERSION 3.12)
include(pico_sdk_import.cmake)
project(MiniWinSimple)
pico_sdk_init()

add_compile_definitions(RASPBERRY_PI_PICO)

include_directories(
...
)

add_executable(MiniWinSimple
...
)

target_link_libraries(MiniWinSimple pico_stdlib hardware_spi hardware_flash)

pico_add_extra_outputs(MiniWinSimple)

If it helps, the project I tried it on is here...

https://github.com/miniwinwm/miniwinwm/tree/master/RaspberryPi/Pico/MiniWinSimple

In my project I added the -std=c99 compiler flag in CMakeCache.txt, after running cmake, like this... //Flags used by the C compiler during all build types. CMAKE_C_FLAGS:STRING=-mcpu=cortex-m0plus -mthumb -std=c99 This line... #include "pico/stdlib.h" eventually includes platform.h, and it's this code that causes the error... inline static int32_t __mul_instruction(int32_t a, int32_t b) { asm ("mul %0, %1" : "+l" (a) : "l" (b) : ); return a; The errors are first it thinks asm is a function and complains about an implicit declaration, then it barfs on the : in the middle as it's not C. I have tried reproducing it using the standard examples, for example blink.c. I made the same change to pico-examples/build/CMakeCache.txt, but the blink project built without error so somehow the -std=c99 compiler flags I made is not getting transmitted through the examples build process. My cmake file is unremarkable... ``` cmake_minimum_required(VERSION 3.12) include(pico_sdk_import.cmake) project(MiniWinSimple) pico_sdk_init() add_compile_definitions(RASPBERRY_PI_PICO) include_directories( ... ) add_executable(MiniWinSimple ... ) target_link_libraries(MiniWinSimple pico_stdlib hardware_spi hardware_flash) pico_add_extra_outputs(MiniWinSimple) ``` If it helps, the project I tried it on is here... https://github.com/miniwinwm/miniwinwm/tree/master/RaspberryPi/Pico/MiniWinSimple
kilograham commented 2021-04-16 08:30:43 -05:00 (Migrated from github.com)

Does it work with __asm instead of asm?

Does it work with `__asm` instead of `asm`?
miniwinwm commented 2021-04-16 09:44:31 -05:00 (Migrated from github.com)

It gets through the asm problem, but then fails on static_assert in address_mapped.h. I think typeof in sem.c is going to be a problem as well. It looks like that one needs to be __typeof.

It gets through the asm problem, but then fails on static_assert in address_mapped.h. I think typeof in sem.c is going to be a problem as well. It looks like that one needs to be __typeof.
kilograham commented 2021-04-16 12:29:21 -05:00 (Migrated from github.com)

Note the best way to specify C99 is to do

project(MiniWinSimple C ASM)
set(CMAKE_C_STANDARD 99)

which will do --std=gnu99 which gets use the asm/typeof stuff. You can add the follow

#ifndef static_assert
#define static_assert _Static_Assert
#endif

for now. you can edit a header, or inject it via the PICO_CONFIG_HEADER_FILES variable:

list(APPEND PICO_CONFIG_HEADER_FILES path/to/foo.h)

and it will be included in all files.

Note the best way to specify C99 is to do ``` project(MiniWinSimple C ASM) set(CMAKE_C_STANDARD 99) ``` which will do `--std=gnu99` which gets use the asm/typeof stuff. You can add the follow ``` #ifndef static_assert #define static_assert _Static_Assert #endif ``` for now. you can edit a header, or inject it via the `PICO_CONFIG_HEADER_FILES` variable: ``` list(APPEND PICO_CONFIG_HEADER_FILES path/to/foo.h) ``` and it will be included in all files.
kilograham commented 2021-04-16 12:31:50 -05:00 (Migrated from github.com)

note that we don't claim to work with C99, however if the changes needed for support arer non invasive we will fix them individually

note that we don't claim to work with C99, however if the changes needed for support arer non invasive we will fix them individually
miniwinwm commented 2021-04-16 14:44:44 -05:00 (Migrated from github.com)

Thanks for your input. I shall work through the problems to see if I can make progress and if it's only trivial changes needed to get it to work I'll add them here.

Thanks for your input. I shall work through the problems to see if I can make progress and if it's only trivial changes needed to get it to work I'll add them here.
Wirtos commented 2021-05-07 03:37:36 -05:00 (Migrated from github.com)

C99 has no static assert, but one might use typedef trick to create one if there's no compiler-specific way

#define concat_(a, b) a##b
#define concat(a, b) concat_(a, b)
#define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1]

static_assert(0, "message"); <- compilation error here
C99 has no static assert, but one might use typedef trick to create one if there's no compiler-specific way ``` #define concat_(a, b) a##b #define concat(a, b) concat_(a, b) #define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1] static_assert(0, "message"); <- compilation error here ```
DwayneGit commented 2023-02-23 12:58:50 -06:00 (Migrated from github.com)

I am running into this problem now with trying to compile.

error: expected declaration specifiers or '...' before string constant
  106 |     static_assert( NUM_TIMERS == 4, "");

if i comment it out all good.

any thoughts to adding a check to all the static_asserts:

#if __STDC_VERSION__ >= 201112L
    static_assert( NUM_TIMERS == 4, "");
#endif

or piggy backing off of @Wirtos adding something like this to pico/assert.h:

#if __STDC_VERSION__ < 201112L
  #define concat_(a, b) a##b
  #define concat(a, b) concat_(a, b)
  #define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1]
#endif
I am running into this problem now with trying to compile. ``` error: expected declaration specifiers or '...' before string constant 106 | static_assert( NUM_TIMERS == 4, ""); ``` if i comment it out all good. any thoughts to adding a check to all the static_asserts: ``` #if __STDC_VERSION__ >= 201112L static_assert( NUM_TIMERS == 4, ""); #endif ``` or piggy backing off of @Wirtos adding something like this to pico/assert.h: ``` #if __STDC_VERSION__ < 201112L #define concat_(a, b) a##b #define concat(a, b) concat_(a, b) #define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1] #endif ```
Wirtos commented 2023-02-23 13:08:55 -06:00 (Migrated from github.com)

I am running into this problem now with trying to compile.

error: expected declaration specifiers or '...' before string constant
  106 |     static_assert( NUM_TIMERS == 4, "");

if i comment it out all good.

any thoughts to adding a check to all the static_asserts:

#if __STDC_VERSION__ >= 201112L
    static_assert( NUM_TIMERS == 4, "");
#endif

or piggy backing off of @Wirtos adding something like this to pico/assert.h:

#if __STDC_VERSION__ >= 201112L
  #define concat_(a, b) a##b
  #define concat(a, b) concat_(a, b)
  #define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1]
#endif

Whoops, that one had a little mistake with concat being unused. Indeed this solution should work in most of the use-cases except static asserts declared inside structs or unions, also could add compiler-specific flags to silence unused warnings about declared typedefs

#define concat_(a, b) a##b
#define concat(a, b) concat_(a, b)
#define static_assert(cond, message) typedef char concat(assertion_on_line_, __LINE__)[(cond) ? 1 : -1]
> I am running into this problem now with trying to compile. > > ``` > error: expected declaration specifiers or '...' before string constant > 106 | static_assert( NUM_TIMERS == 4, ""); > ``` > > if i comment it out all good. > > any thoughts to adding a check to all the static_asserts: > > ``` > #if __STDC_VERSION__ >= 201112L > static_assert( NUM_TIMERS == 4, ""); > #endif > ``` > > or piggy backing off of @Wirtos adding something like this to pico/assert.h: > > ``` > #if __STDC_VERSION__ >= 201112L > #define concat_(a, b) a##b > #define concat(a, b) concat_(a, b) > #define static_assert(cond, message) typedef char assertion_on_line_##__LINE__[(cond) ? 1 : -1] > #endif > ``` Whoops, that one had a little mistake with concat being unused. Indeed this solution should work in most of the use-cases except static asserts declared inside structs or unions, also could add compiler-specific flags to silence unused warnings about declared typedefs ```c #define concat_(a, b) a##b #define concat(a, b) concat_(a, b) #define static_assert(cond, message) typedef char concat(assertion_on_line_, __LINE__)[(cond) ? 1 : -1] ```
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#339
No description provided.