STM8开发:COSMIC编译器报missing prototype错误的语法疑问
void to your function prototype fixes that COSMIC STM8 error? Let’s break this down clearly, including a critical bug in your code you might not have noticed:
1. This isn’t just a compiler quirk—it’s a C language rule
In the original C89 standard, there’s a key difference between these two declarations:
int * UART1_ReceiveBytes();: This tells the compiler "this function exists, but I’m not specifying its parameters"—it’s an old-style function declaration that allows any number/type of arguments.int * UART1_ReceiveBytes(void);: This explicitly tells the compiler "this function takes no arguments"—this is the standard, modern way to declare a parameterless function.
While newer C standards (C99+) are more lenient with old-style declarations, embedded compilers like COSMIC for STM8 often enforce strict compliance to avoid bugs. It sees the first form as an incomplete prototype (since it doesn’t define the parameter list), hence the #error cpstm8 main.c missing prototype message. Adding void gives the compiler a complete, unambiguous prototype that meets its requirements.
2. Why your initial prototype didn’t work
Your first declaration int * UART1_ReceiveBytes(); is a function "declaration" but not a "complete prototype" in the eyes of COSMIC. The compiler needs a clear definition of the function’s parameters to validate calls (like your p = UART1_ReceiveBytes(); line) and ensure type safety. Without void, it treats the declaration as incomplete and throws the error.
3. A big issue with your UART1_ReceiveBytes function
Wait—there’s a critical bug in your code that you need to fix right away: you’re returning a pointer to a local stack array!
int * UART1_ReceiveBytes(void) { int i = 0; int buf [3] = {0x30, 0x30, 0x30}; // This lives on the stack // ... receive logic ... return buf; // ❌ Bad! buf is destroyed when the function returns }
When the function finishes executing, the stack space used for buf gets reclaimed. The pointer you return becomes a "dangling pointer"—using it later will lead to undefined behavior (garbage data, crashes, etc.).
Here are two simple fixes:
- Declare
bufasstaticto keep it in static memory (persists after the function ends):static int buf[3] = {0x30, 0x30, 0x30}; - Or pass a pre-allocated buffer from the caller (better for reusability and avoiding static state):
// Rewrite the function to accept a buffer pointer void UART1_ReceiveBytes(int *buf) { int i = 0; if (UART1_GetFlagStatus(UART1_FLAG_RXNE) != RESET) { do { buf[i] = UART1_ReceiveData8(); i++; delay_ms(10); } while(i != 3); UART1_ClearFlag(UART1_FLAG_RXNE); } } // Call it like this in main: void main(void) { while (TRUE) { int buf[3] = {0x30, 0x30, 0x30}; UART1_ReceiveBytes(buf); // Use buf here } }
内容的提问来源于stack exchange,提问作者Ghedim

