Why does calling system() without including stdlib.h still work? - c

The only library I've included in my C program is stdio.h. Calling system() within that very same program works anyway, though Eclipse complains about an implicit declaration of function ‘system’ [-Wimplicit-function-declaration], whatever that means.
However, GCC (the compiler I'm using) seems happy. Would it be that Eclipse is automatically fixing the issue before compilation, or is GCC just kind enough to do that without complaining? I understand nothing of this.
I'm using GNU/Linux Debian 11 (Bullseye) Stable, if that makes any difference.

Once upon a time, the rule in C was that if you called a function the compiler had never heard of, it quietly assumed it was an ordinary function returning int.
The system() function fits that description.
In more recent versions of the C Standard, the "implicit int" rule has been removed, and you are required to declare all functions before calling them. A modern compiler is obliged to issue a diagnostic if you fail to declare a called function. However, there's nothing keeping the compiler from having the diagnostic be a nonfatal warning, and going on to compile your program anyway, making use of the old assumption. And in fact, many compilers still do that, perhaps to make it easier to compile old code written under the old rules.

Related

When to use -std=c11 while compiling a C source code using ubunto

I am trying to compile a C source code to a machine code using an ubunto terminal
My tutor instruction was to use the following command:
running clang myprogramm.c -std=c11
Why shall I use the keyword -std=c11 and what is the difference to using just
clang myprogramm.c
Using std= options is required by your tutor (I'm divinig her motives, I'm particularly good at this!) because she wants to make sure you stay away from all those nifty Clang features that turn the accepted language from C to A LANGUAGE SUPERFICIALLY LOOKING LIKE C BUT ACTUALLY A DIFFERENT LANGUAGE NOT SUPPORTED BY OTHER C COMPILERS.
That is more than just additional library functions. It include syntax changes that break the grammar of Standard C, as defined by ISO. A grasshopper should not use these while learning. Using -std=c11 makes sure Clang either warns about or even rejects, with an error, such constructs.
When to specify the standard? Whenever you use the compiler. It is never a good idea to let the compiler just use whatever it wants.
If someone tries to use a compiler that is too old, then they will get a warning or error, and they will understand why the compile fails.
If a code contributor (maybe even yourself!) tries to add code using features that are too new, their code will be rejected. That's very important if you intend to keep compatibility with an older standard.
By explicitly stating the standard, using new features or extensions are a choice and don't happen by accident.

GCC how to stop false positive warning implicit-function-declaration for functions in ROM?

I want to get rid of all implicit-function-declaration warnings in my codebase. But there is a problem because some functions are
programmed into the microcontroller ROM at the factory and during linking a linker script provides only the function address. These functions are called by code in the SDK.
During compilation gcc of course emits the warning implicit-function-declaration. How can I get rid of this warning?
To be clear I understand why the warning is there and what does it mean. But in this particular case the developers of SDK guarantee that the code will work with implicit rules (i.e. implicit function takes only ints and returns an int). So this warning is a false positive.
This is gnu-C-99 only, no c++.
Ideas:
Guess the argument types, write a prototype in a header and include that?
Tell gcc to treat such functions as false positive with some gcc attribute?
You can either create a prototype function in a header, or suppress the warnings with the following:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
/* line where GCC complains about implicit function declaration */
#pragma GCC diagnostic pop
Write a small program that generates a header file romfunctions.h from the linker script, with a line like this
int rom_function();
for each symbol defined by the ROM. Run this program from your Makefiles. Change all of the files that use these functions to include romfunctions.h. This way, if the linker script changes, you don't have to update the header file by hand.
Because most of my programming expertise was acquired by self-study, I intentionally have become somewhat anal about resolving non-fatal warnings, specifically to avoid picking up bad coding habits. But, this has revealed to me that such bad coding habits are quite common, even from formally trained programmers. In particular, for someone like me who is also anal about NOT using MS Windows, my self-study of so-called platform-independent code such as OpenGL and Vulkan has revealed a WORLD of bad coding habits, particularly as I examine code written assuming the student was using Visual Studio and a Windows C/C++ compiler.
Recently, I encountered NUMEROUS non-fatal warnings as I designed an Ubuntu Qt Console implementation of an online example of how to use SPIR-V shaders with OpenGL. I finally threw in the towel and added the following lines to my qmake .PRO file to get rid of the non-fatal-warnings (after, first, studying each one and convincing myself it could be safely ignored) :
QMAKE_CFLAGS += -Wno-implicit-function-declaration
-Wno-address-of-packed-member
[Completely written due to commends]
You are compiling the vendor SDK with your own code. This is not typically what you want to do.
What you do is you build their SDK files with gcc -c -Wno-implicit-function-declaration and and your own files with gcc -c or possibly gcc -o output all-your-c-files all-their-o-files.
C does not require that declarations be prototypes, so you can get rid of the problem (which should be a hard error, not a warning, since implicit declarations are not valid C) by using a non-prototype declaration, which requires only knowing the return type. For example:
int foo();
Since "implicit declarations" were historically treated as returning int, you can simply use int for all of them.
If you are using C program, use
#include <stdio.h>

C compiles with an undefined symbol

I am using an older version of the Diab C compiler.
In my code I have taken a function name and redefined it as a function pointer with the same signature. Before making this change the code worked. After the change it made it caused the embedded system to lock up.
The function pointer was declared extern in a header, defined in one .c file, and used in another .c file. When it was called from the second .c file it would cause the system to lock up. When I attempted to add debug information using sprintf it finally told me that it was an undefined symbol. I realized that the header file was was not included in the second .c file. When I #included it everything compiled and worked correctly.
My question is, is there some C rule that allowed the compiler to deduce the function signature even though the symbol was undefined at the call location? To my understanding there should have been an error long before I made any changes.
If no declaration is available, the compiler uses a default declaration of a function taking an unknown number of arguments and returning an int. If you turn up compiler warnings (eg -Wall -Wextra -Werror with gcc, check the documentation for your compiler), you should get a compile time warning.
Most likely, the code at first worked because it was compiled in the C89 or similar mode. The C standard from 1989 allows calling functions without first declaring them.
When you changed the code to use a pointer but didn't include the declaration of the pointer, the compiler assumed that your pointer was in fact a function and generated code to call into the pointer, as if the pointer had executable code inside. As the result, the program understandably stopped working.
What you should do is enable all possible warnings (for gcc: -Wall, -Wextra and make sure optimization is enabled (-O2 is good) because it enables code analysis), especially for calling functions without prototypes. A better thing might be to switch the compiler into the C99 mode (-std=c99 in gcc) or switch to a C99 compiler. The C standard from 1999 prohibits calling functions without prototypes and comes with some useful features absent in C89.

Problems with different IDEs for C programming

I'm learning C for 2 months. I experimented with different IDEs and my experiments resulted in confusion. Because for e.g. in NETBEANS I can use abs function without stdlib.h library, but when I tried to do the same thing in Visual Studio 2012 it gave a an error. Or a very odd thing in NETBEANS I can use functions from math.h library without declaring the library. Why is this happening? Can someone help? NETBEANS USES cygwin compilers.
In C you don't need to include the headers in order to use the functions. Older compilers don't always warn about that though. Also, different compilers might provide those functions in different ways; on some, they're not functions but macros. With macros, you need to include the headers.
It's good practice to always include the headers that provide the functions you need, so that you get the function prototypes. That's the only way the compiler can check for errors (correct types of passed function arguments, for example.) If you call a function for which you have no prototype, you get an implicit declaration of that function. That means the compiler just takes a guess and hopes you're using the function correctly, but has no way to check. That's why this won't work with macros, since a macro can't have a function declaration (implicit or not.)
The reason Visual Studio gives an error is because it's a C++ compiler, not a C compiler. C++ is a bit different from C. One of the differences is that C++ does not allow implicit function declarations. If you don't declare the functions you use (by including their header file in this case), then that's considered an error. C++ is mostly compatible with C, but that happens to be one of the few differences.
Btw, they're not libraries. They're header files. There's a difference. You have several standard headers you can include, but you only have one library; the C library. On most systems, you also have a math library, which only contains math functions. The point though is that several header files can be (and usually are) part of the same library.
my experience with C has been the same. different compilers has different libraries and sometimes they don't stick to the standards.
some compiler vendors try to lock you in (XXXXX$XXX) :)

Why am I able to compile and run C programs without including header files?

I have tested this fact on Turbo C++ 3.0, VC++ 2008 express and Borland C++ 6.
If I add a C program with *.C extension to the project, I am able to compile and run the program without including header files. But in this case, some functions (like sqrt(), etc..) are returning erroneous values.
If I add a C program with *.CPP extension to the project, I am not able to compile and run the program without including header files.
Why?
In C, when the compiler does not find the definition of a function, it assumes it's an external function returning an integer. So the code compiles, and if the linker then finds a function with corresponding name it will run as well. But possibly with unexpected results.
By default in C function return type is int, and even if prototype not declared you'll be able to use, for example, libc functions. Of course, if its return value not int, you've got erroneous values.
C++ are more stricter and disallow this.
Also, gcc implements some functions as built-ins. You can try compiling with -fno-builtin options, if you use it.
If you don't provide a declaration for a function, C makes a guess at it. This guess is almost always wrong, hence your "erroneous values". C++ doesn't do this.
The C++ standard requires a function prototype to be seen before a function is used.
C does not have this requirement. If a C compiler sees an undeclared function it creates an implicit declaration assuming that the function returns int. If the function doesn't really return int unpredictable things will happen, as you are seeing with sqrt.

Resources