0

I am currently "playing" around in a quite big and old codebase and, quite unfortunately, it has no fixed style attached to it. So it was just made to work but that also means that quite a lot of it can be described as spaghetti code.

I came across something that I do not fully undersand. Compiler is from ARM/KEIL and it is for an embedded system.

first file:

fileA.c
// prototype
int GetSomething( int a );

// implementation
int GetSomething( int a) {
    DoSomething();
}

second file:

fileB.c
// prototype
int GetSomething( int a )

void main ( void ) {
    GetSomething(10);
}

There are no headers which have a declaration for the function GetSomething but the function is still correctly linked. Originally, there are a extern keyword in the second file in the declaration of GetSomething, but with or without that results in the same binary. The code has been tests and works.

I've seen Stackoverflow Question but that doesn't seem to cover my case as it seems to have nothing to do with the extern keyword.

I hope that somebody can explain that to me or tell me what is going on. Thanks.

8
  • There is nothing special about header files. They are only used to ensure that multiple files use same declarations. If you provide a correct prototype directly in your .c file then this is the same as putting it into a header file. It's just more effort to keep everything in sync. Commented Aug 16, 2022 at 7:52
  • For function prototypes, extern is default. Commented Aug 16, 2022 at 7:53
  • Header file is just text. When you write #include the content of the file literally is replacing #include. You can have no headers, just paste the same stuff around. Btw, you may want to start by refactoring your codebase, so the same stuff is in headers. Commented Aug 16, 2022 at 7:53
  • 2
    Yes, that is poor design. In a code review I wouldn't accept code where such functions are not placed in a header that is then included both in the file where it is defined and where it is used. If you don't do that you cut your compiler's abilities to detect mismatches in declarations. Commented Aug 16, 2022 at 8:13
  • 1
    I work on a codebase with a forty-year history. Before there was a standard, the was no way to enforce function signatures, and there was no void for return types or empty argument lists. When prototypes were added, it was easier to copy the declaration into the file than to create a header that did the job properly (or get someone on another part of the team responsible for the code that provided the service to create the header), so that's what people under time pressure did. And it becomes a major PITA when the function signature changes. Use headers! Commented Aug 16, 2022 at 11:57

1 Answer 1

2

Using header files and #include directives are just a more organized and neater way to use various parts of code in a program at different places.

When you do something like #include "header.h" a copy of header.h is put into the file.

So when you write

GetSomething( int a );

you are essentially doing an alternative to what #include would normally do.

Another important detail is that function prototypes have the extern storage class specifier by default.

One thing you should keep in mind is that declaring function prototypes across your files manually can result in error prone and hard to maintain code. So it is best to utilize header files and #include directives.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.