Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does not build for strict C99 #339

Open
miniwinwm opened this issue Apr 14, 2021 · 10 comments
Open

Does not build for strict C99 #339

miniwinwm opened this issue Apr 14, 2021 · 10 comments

Comments

@miniwinwm
Copy link

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
Copy link
Contributor

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

@miniwinwm
Copy link
Author

miniwinwm commented Apr 16, 2021

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

@raspberrypi raspberrypi deleted a comment from lurch Apr 16, 2021
@kilograham
Copy link
Contributor

Does it work with __asm instead of asm?

@miniwinwm
Copy link
Author

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
Copy link
Contributor

kilograham commented Apr 16, 2021

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
Copy link
Contributor

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
Copy link
Author

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
Copy link

Wirtos commented May 7, 2021

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
Copy link

DwayneGit commented Feb 23, 2023

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
Copy link

Wirtos commented Feb 23, 2023

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]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants