2

I'm trying to understand an old code not writte by me.

I've a file called task.c with its task.h. On the task.c, at the very beginning there's

#define TASK
  #include "task.h"
#undef
#include "main.h"
...

extern struct s_system sys;

and in the task.h there's

#ifndef TASK
  extern void myfunc(struct my_Struct *);
  ...
#endif

I'm trying to understand why it has been build like this instead of just include the .h in the .c like #include "task.h"

My question also comes to the fact that the compiler (I'm using IAR 9.20.4) shows a warning saying that

Warning[Pe231]: declaration is not visible outside of function

on every line of extern void myfunc(struct my_Struct *);

NicoCaldo
  • 1,171
  • 13
  • 25
  • `struct my_Struct` is not visible outside of function. – 273K Jul 18 '23 at 07:53
  • *why it has been build like this* You might want to ask the author. `extern` in function declarations is odd. – 273K Jul 18 '23 at 07:54
  • @273K what if the author can't be reached...? – NicoCaldo Jul 18 '23 at 07:59
  • 2
    `why it has been build like this instead of just include the .h in the .c` Incompetence? Negligence? Hurry? We can only guess - I do not think this is a programming question. `#undef` without anything after is an error with gcc. – KamilCuk Jul 18 '23 at 08:32
  • @KamilCuk sorry, didn't know that the thinhs after `#undef` were important. Just update my question as, there are other .h included after that – NicoCaldo Jul 18 '23 at 08:38
  • @273K How is that odd? That is normal in header files, it is better than nothing. It is better to have either a `extern` declaration somewhere or a `static` definition than nothing of both. – 12431234123412341234123 Jul 18 '23 at 08:41
  • 1
    @12431234123412341234123 Extern is implicit when declaring a function at file scope and typically is omitted. – KamilCuk Jul 18 '23 at 08:53
  • @KamilCuk Explicit is better than implicit. Use `extern` to show that you really intend to make it visible to other translation units. Using neither `extern` nor `static` smells like bad code to me. – 12431234123412341234123 Jul 18 '23 at 08:55
  • 3
    Insufficient context to answer your question. Clearly the author wanted to be able to conditionally exclude that function declaration. Although function declarations themselves are benign if they are not referenced. Possibly the idea was to be able to trap unintended usages of that function, or to allow its redefinition with a different signature. Either way, I would not regard it as an example of good practice (especially if its usage is not documented by a clear comment), and whatever it was intended to achieve there are most likely other methods. – Clifford Jul 18 '23 at 09:27
  • Since you are defining `TASK` it is not clear how there are any instances of `extern void myfunc(struct my_Struct *);`to produce error `Pe231`. We'd need to see the code where these `extern` declarations occur (or where (else) task.h is included without `TASK` being defined perhaps.). – Clifford Jul 18 '23 at 09:30
  • Also note that the fact that your code is intended for an embedded target makes no difference in this case - it is not an embedded question – Clifford Jul 18 '23 at 09:32
  • @Clifford it's a warning – NicoCaldo Jul 18 '23 at 09:36
  • 2
    #undef alone is not valid. Please show the exact code. – Yves Daoust Jul 18 '23 at 09:40
  • 1
    @NicoCaldo that is hardly relevent. Compiler warnings are often semantic errors. You'd have done better to clarify your question in the manner suggested that to get pedantic about my comment. You are asking us to describe a whole room by looking through a keyhole. Suffice to say that this code is not idiomatic, and it's purpose is unclear and peculiar to this particular codebase. No _general_ explanation is possible from the information presented. – Clifford Jul 18 '23 at 10:20
  • Are there more declarations in the file "task.h" than function declarations, which are guarded by this `#ifndef`? – the busybee Jul 18 '23 at 10:27

1 Answers1

3

Since you are getting the message “declaration is not visible outside of function”, then somebody made a mistake somewhere sometime.

By itself, extern void myfunc(struct my_Struct *); declares struct my_Struct with function prototype scope. It is a new type each time it is declared and is visible only inside the declaration of the function. It is not even the same type between two instances of that function declaration or between an instance of that function declaration and the function definition, even though the name is the same, struct my_Struct.

To be correct, the type struct my_Struct must be declared outside of any function and before those declarations. Then the references to it inside the function declarations will use the visible type instead of declaring a new type. (The simple declaration struct my_Struct suffices for this. The definition of the structure contents can be elsewhere, visible where they are used.)

We do not know what error occurred where or when. It could be an error writing the code, and error editing the code, and error modifying the project’s build process, or a failure to update the code when changing from some old version of C to a modern version. Revision history of the project might contain a clue.

In any case, add struct my_Struct; to the code.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312