C89 mode in compilation of C library

Hi

I'm trying to compile www.roland-riegel.de - sd-reader: MMC/SD/SDHC card library lib to access to an SD card

It works now perfectly well
BUT I have to do some modification to this lib to make it compile in C89 mode (as arduino uses this mode to compile C files) (the lib perfectly compiles in C99 mode)
Or it compiles also if I rename *.c files in *.cpp

Hence my question, why arduino compiles in C89 files .c, and in C99 files .cpp ?

Why not compiling everything in C99 mode ?

Thanks

c89 is the default in gcc; their C99 support is "incomplete." Arduino is just using the default.

I assume C++ is simply more C99-like than C89-like ?

Yes maybe

And by the way,I've seen that people just change *.c files in *.cpp for a lib to work in arduino

Hence my question, isn't it possible to just put a C lib in arduino ? (not a C++ one)

because renaming *.c in *.cpp is crapy...

isn't it possible to just put a C lib in arduino ?

Well, sure. I just recently wrote a library to implement a polled PS2 keyboard driver. It's all in C, and it all lives in .../hardware/libraries/ps2keypolled/*.c; a sample sketch that uses it compiles just fine using the standard mechanism for "import library"

It's relatively normal for a significantly sized C program to need some editing in order to compile, when moving from one compiler to another (or even from one version of a compiler to another.) Compiler writers almost seem to have a habit of interpretting each ambiguity in the language specifications in the maximally incompatible way... Especially on microcontrollers where exact conformance to the rigors of a language may not be in the best interests of the users...

Ok thanks !

And last question, roland lib I'd like to compile is C99 compliant

How can I force arduino to compile in C99 mode ?
In fact i've looked at all the Makefile in arduino, and they all use gnu99 (which is C99 + some gcc extensions)

So if arduino uses nearly everywhere gnu99 mode compilation, it should also compile lib in gnu99, I think, no ?

i've done rgrep CSTANDARD to check which mode is used, and it's always gnu99
Maybe in the file where lib are told to be compiled, a CSTANDARD is missing... ?

Thanks !

In fact i've looked at all the Makefile in arduino, and they all use gnu99

But none of the "Makefile" files in the arduino directory hierarchy are involved when using the IDE to compile libraries OR sketches. Most of them are for compiling host-side utilities associated with Firmata or the bootloaders, and ONE (hardware/cores/arduino/Makefile) is a semi-supported thing for compiling sketches outside of the IDE. When you compile sketches from INSIDE the IDE, the "-std" option is not used. (It is "interesting" that the option is included in the Makefile but not on the compile lines produced by the IDE. Perhaps this is a "bug." (although I think it's more likely that "Makefile" is based on some standard format that someone used without checking how exactly it ends up matching what the IDE uses.) (Set build.verbose in the Arduino preferences file to see the commands that the IDE generates.))

To follow this post, i've given a proposal feature

Would be nice to have it
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1237478695/0

Humm well in fact
I can compile roland riegel library C files (just change the for(uint8_t i=0... in uint8_t i; for(i=0...) in order to be C89 compliant)

But when i import it, i get an error, it says function in C lib doesn't exist, and if i rename the file that contains this function from *.c to *.cpp
and compile again the lib

Then it compiles fine, and the sketch compiles

I'm not sure at all arduino can compile a C library in fact

Would you be interested to testing compiling roland lib ?
Very easy to do (except this problem of renaming file in cpp)

Thanks

Sure, I'll give it a try. You're starting just by moving all the .c and .h files into hardware/library/sd-reader or similar directory? What does your sketch look like?

Cool !

In fact i've taken the officiel lib and change a .h to support my 328P, and change 2 inline functions, you can get the source here:

http://www.despatis.com/arduino/sd-reader_source_20081121-arduino.tgz

One you have it, you just put it in hardware/libraries, eventually rename the dir to SDcard, and launch arduino

It should compiles nicely, with no error, and then you take the example sketch in http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1206874649, it's in the second post (by agent_orange)

Tell me if your sketch compile. For me it says sd_raw_init is missing

Thanks !!

It looks to me like there are still lots of errors, but they aren’t being reported in the arduino build window.
I see no .o files created in the library directory, and if I manually duplicate the build line that the arduino IDE uses, I DO get errors (the for loop issue you mentioned.):

 /Downloads/arduino-0014/hardware/tools/avr/bin/avr-gcc -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=16000000 -I. sd_raw.c
sd_raw.c: In function 'sd_raw_init':
sd_raw.c:204: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c:215: error: conflicting types for 'i'
sd_raw.c:204: error: previous definition of 'i' was here
sd_raw.c:215: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c:261: error: redefinition of 'i'
sd_raw.c:215: error: previous definition of 'i' was here
sd_raw.c:261: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c: In function 'sd_raw_send_command':
sd_raw.c:422: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c: In function 'sd_raw_read':
sd_raw.c:495: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c: In function 'sd_raw_write':
sd_raw.c:732: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c: In function 'sd_raw_get_info':
sd_raw.c:867: error: 'for' loop initial declaration used outside C99 mode
sd_raw.c:920: error: redefinition of 'i'
sd_raw.c:867: error: previous definition of 'i' was here
sd_raw.c:920: error: 'for' loop initial declaration used outside C99 mode
BillW-MacOSX-2<1660> /Downloads/arduino-0014/hardware/tools/avr/bin/avr-gcc -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=atmega168 -DF_CPU=16000000 -I. fat.c
fat.c: In function 'fat_append_clusters':
fat.c:509: error: 'for' loop initial declaration used outside C99 mode
fat.c: In function 'fat_interpret_dir_entry':
fat.c:1553: error: 'for' loop initial declaration used outside C99 mode
fat.c: In function 'fat_write_dir_entry':
fat.c:1839: error: 'for' loop initial declaration used outside C99 mode
fat.c:1843: error: 'for' loop initial declaration used outside C99 mode
fat.c: In function 'fat_get_fs_free_16_callback':
fat.c:2286: error: 'for' loop initial declaration used outside C99 mode
BillW-MacOSX-2<1664>

I usually see SOME of these errors the first time I start up the IDE, but I don’t see them if I do my usual “force library rebuild” hack of changing the board type. This is certainly a bug of some kind…

I’ll look at it more later. I need to go to sleep…

OUPS sorry, i've forgotten to add more tuning in the code to make it C99 friendly

It's done, you can test it, it compiles fine, i've tested

Ah hah! The problem is in the ".h" files.
They are missing the:

#ifdef __cplusplus
extern "C"{
#endif
  // Bulk of the .h file
#ifdef __cplusplus
}
#endif

framing that is needed if you're going to defined external C functions from within a c++ program (the sketch file is compiled as c++.)

Ah yes it compiles and i can use the functions in the script thanks !!

Well now, i've a problem with the function, but that's another story :slight_smile:

Of course, if someone has successfully run LAST roland riegel lib, I'm very interested !

For now, all is ok, but sd_raw_init() returns 0, because of the code:
if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address * 512))
{ unselect_card(); return 0; }

in fact sd_raw_send_command() doesn't return false, hence the code in brackets is executed resulting in a return 0 (failure)

If anyone has an idea...

Hum after several mail with Roland Riegel, we’ve found the way to make the lib work, you just need to comment the 2 lines in sd_raw_init:

SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 /
SPSR |= (1 << SPI2X); /
Doubled Clock Frequency: f_OSC / 2 */

When Roland will release a new version of the lib with several fixes, I’ll do a post to explain how to make it work easily (needs some specific fix for arduino, and all go fine)

In order to have a real excellent solution to write to an sd card…

if I do my usual "force library rebuild" hack of changing the board type.

Incidentally, I think I've discovered that it will rebuild them even if you choose the already selected board--which is quicker.

--Phil.