Need Help with PropGCC (Function types & prototypes) [SOLVED]

I thought it would be a fun diversion to port my TM1637 driver to C -- I am now regretting that, but angry enough not to quit.
I keep getting silly warnings like this:
...but when I add function prototypes, things get even worse:
Why? Why is PropGCC giving my functions an implicit type when I am EXPLICITLY declaring them as void or uint8_t?
I keep getting silly warnings like this:
TM1637_Demo.c:45:3: warning: implicit declaration of function 'tm1637_begin' [-Wimplicit-function-declaration]
TM1637_Demo.c:46:3: warning: implicit declaration of function 'tm1637_write' [-Wimplicit-function-declaration]
TM1637_Demo.c:47:3: warning: implicit declaration of function 'tm1637_end' [-Wimplicit-function-declaration]
...but when I add function prototypes, things get even worse:
TM1637_Demo.c:45:3: warning: implicit declaration of function 'tm1637_begin' [-Wimplicit-function-declaration]
TM1637_Demo.c:46:3: warning: implicit declaration of function 'tm1637_write' [-Wimplicit-function-declaration]
TM1637_Demo.c:47:3: warning: implicit declaration of function 'tm1637_end' [-Wimplicit-function-declaration]
Why? Why is PropGCC giving my functions an implicit type when I am EXPLICITLY declaring them as void or uint8_t?
Comments
Here is the corrected code; this compiles as expected.
// ================================================================================================= // // File....... TM1637_Demo.c // *** work in progress *** // Purpose.... Demonstration code for TM1637 modules // Author..... Jon "JonnyMac" McPhalen // Copyright (c) 2019 Jon McPhalen // -- MIT license applies // E-mail..... jon@jonmcphalen.com // Started.... // Updated.... 18 DEC 2016 // // ================================================================================================= #include <propeller.h> #include <stdint.h> #define WR_DATA 0x40 #define RD_BTN 0x42 #define WR_FIXD 0x44 #define DSP_OFF 0x80 #define DSP_ON 0x88 #define WR_SEGS 0xC0 uint32_t cmask; uint32_t dmask; uint8_t size; uint8_t buffer[6]; uint8_t tm1637_setup(uint8_t cpin, uint8_t dpin, uint8_t ncols); void tm1637_clear(); void tm1637_fill(uint8_t segments); void tm1637_set_segments(uint8_t col, uint8_t segments); uint8_t tm1637_send_command(uint8_t cmd); void tm1637_start(); uint8_t tm1637_write(uint8_t b) ; uint8_t tm1637_read(); void tm1637_stop(); uint8_t tm1637_setup(uint8_t cpin, uint8_t dpin, uint8_t ncols) { cmask = 1 << cpin; // create masks for pins dmask = 1 << dpin; if ((ncols >= 2) && (ncols <= 6)) // set display size size = ncols; else size = 4; DIRA &= ~cmask; // float pin OUTA &= ~cmask; // write 0 to output bit DIRA &= ~dmask; OUTA &= ~dmask; return tm1637_send_command(0); // verify defice connected } void tm1637_clear() { tm1637_fill(0); } void tm1637_fill(uint8_t segments) { for (uint8_t i = 0; i < 6; i++) buffer[i] = segments; tm1637_start(); tm1637_write(WR_SEGS); for (uint8_t i = 0; i < 6; i++) tm1637_write(segments); tm1637_stop(); } void tm1637_set_segments(uint8_t col, uint8_t segments) { if (col >= size) return; buffer[col] = segments; tm1637_start(); tm1637_write(WR_SEGS); tm1637_write(segments); tm1637_stop(); } uint8_t tm1637_send_command(uint8_t cmd) { tm1637_start(); uint8_t ackbit = tm1637_write(cmd); tm1637_stop(); return ackbit; } void tm1637_start() { DIRA &= ~cmask; // float pins to pull-ups DIRA &= ~dmask; // 5us delay DIRA |= dmask; // dio low // 5us delay DIRA |= cmask; // clock low } uint8_t tm1637_write(uint8_t b) { for (uint8_t i = 0; i < 8; i++) { if (b & 0x01 == 1) DIRA &= ~dmask; else DIRA |= dmask; b >>= 1; // 5us delay DIRA &= ~cmask; // 5us delay DIRA |= cmask; } DIRA &= ~dmask; // 5us delay DIRA &= ~cmask; // 5us delay uint8_t ackbit = (INA & dmask == 0) ? 0 : 1; DIRA |= cmask; return ackbit; } uint8_t tm1637_read() { uint8_t b = 0; uint8_t mask = 0x80; DIRA &= ~dmask; for (uint8_t i = 0; i < 8; i++) { DIRA &= ~cmask; // 5us delay if (INA & dmask) b |= mask; mask >>= 1; DIRA |= cmask; // 5us delay } DIRA |= dmask; // 5us delay DIRA &= ~cmask; // 5us delay DIRA |= cmask; } void tm1637_stop() { DIRA |= cmask; DIRA |= dmask; // 5us delay DIRA &= ~cmask; // 5us delay DIRA &= ~dmask; } // ------------------------------------------------------------------------------------------------- void main() { while (1) { // do something } }
The two warning blocks seems the same to me (wrong copy/paste ?), anyway, C see declarations from top to down in the source, whenever you call a function that is defined after it assumes a standard declaration, then it throws a warning if the actual definition is different.
In your code, tm1637_begin and tm1637_end are not present (this will give you an error in the linker phase), tm1637_write is used in the fill function but defined later after the start function.
If you uncomment the function declarations at top, you should be fine (well, after adding a semicolon after the fill prototype).
Or reorder the functions so they call only functions defined before them, if possible.
To fix up the compile errors, try replacing your currently commented out block of function declarations with this code:
uint8_t tm1637_setup(uint8_t cpin, uint8_t dpin, uint8_t ncols); void tm1637_clear(); void tm1637_fill(uint8_t segments); void tm1637_set_segments(uint8_t col, uint8_t segments); void tm1637_start(); uint8_t tm1637_write(uint8_t b) ; uint8_t tm1637_read(); void tm1637_stop(); uint8_t tm1637_send_command(uint8_t cmd); void tm1637_end(); void tm1637_begin(); void tm1637_end() { } void tm1637_begin() { }
You were missing a couple functions, and also the _fill declaration was missing a semicolon at the end of the line.
One other thing... Do those if/else constructs require curly braces ?
Oh- and also the For loops ? I'm not sure about that.
These code snippets seem to compile OK from Jon's example in SimpleIDE.... at least there's no reported errors.
if ((ncols >= 2) && (ncols <= 6)) // set display size size = ncols; else size = 4;
and
for (uint8_t i = 0; i < 6; i++) tm1637_write(segments);
However, are curly braces required to ensure the code operates as expected ? What are the rules about that ?
It looks like "braces not required when code follows on 1 line only".... Is that a correct assumption ?
They look great for Spin (indented) though
That makes it very clear; Thanks @Wuerfel_21
-std=c99
when declaring the i variable in statements like:for (uint8_t i = 0; i < 6; i++)
dgately
My syntax is correct. I'm not a master of C, but I know it well enough to get syntax right (and I keep a few books handy to double-check when I have questions).
The compiler setting (-std=C99) was already in place.
I apologize... I may have caused bit of confusion by renaming a couple functions after posting the original warnings. These are the warnings with the code above (function prototypes commented out).
These are the warnings when I remove the comment block from the function prototypes.
This is a lot better in recent GCC versions (due to GCC's monopoly on being a decent C/C++ compiler being disturbed by clang/LLVM), but alas, no one maintained the Prop version.
It compiles now.
I understand. I am -- at the moment -- simply translating my Spin library code to C. Once everything is working I will move the move things to the .h and .c files as one would expect with a proper library.
To those, especially @Wuerfel_21, who assisted, thank you.
A lot of the translation from Spin to C can be automated via spin2cpp, if you'd like to save time.
I could, but it would deny me the opportunity to learn as I go. For me this is about learning, not about saving time.
I have several text files where I keep notes about language conversions so I don't have to keep relearning what to do.
I don't know what system you use but it's a good idea to keep notes on what to do or what to be careful of.
As for style, I prefer to indent braces under the function or statement that they go with.