getchar_unlocked() implicit declaration in C99 - c

Using getchar_unlocked and compiling with --std=c99 flag gives warningas follows-
warning: implicit declaration of function ‘getchar_unlocked’ [-Wimplicit-function-declaration]
Does not give any warning if compiled without flag.Is there any way to work around with it ?

Starting from C99 you must have a visible function prototype before calling a function. While the earlier C standard would just stupidly assume that any function unknown to the compiler has the format int func (params), which in turn would cause severe bugs most of the time.
Properly declare a prototype for getchar_unlocked and the bug will go away.
Note that there is no such function present in any standard library. It seems you might have to include some non-standard library for the compiler to find the function.

_unlocked versions of get... functions are POSIX extensions. They are not part of the standard functions of C99. The full list of get... functions is given in 7.19.1.5: getwc, getwchar, getc, getchar, and gets (deprecated).
When the function is not on this list, C99-compliant compiler must warn you that your program may not compile with other C99-compliant compilers.

Dialect selection options like -ansi and -std=c99 cause the compiler to define certain macros (in addition to altering the accepted dialect).
Library header files react to those macros.
Precisely how they react is quite system-dependent (the compiler doesn't provide a C library), but a common behavior you can broadly expect is that if you use one of these flags alone (without any other "feature selection macro"), it has the effect of hiding the declarations of functions, macros and other global symbols which are not in the specified ISO C dialect.
ISO C knows nothing about getchar_unlocked. The presence of such a declaration in <stdio.h> (normally an ISO C header) is a POSIX extension, which is basically nonconforming, since getchar_unlocked is an identifier that strictly conforming C programs can use, even if they include <stdio.h>. When you use -ansi or -std=c99, the <stdio.h> header listens up and whips itself into ISO-C-conforming shape, hiding such extensions.
On well-behaved POSIX systems, you can request that you want an ISO C dialect and that you want certain rudimentary 1990-ish POSIX features to be visible in header files, for instance like this:
gcc -std=c99 -D_POSIX_SOURCE ...
^^^^^ "feature selection macro"
There is a whole science to these feature selection macros, too broad for this question and answer; some forms of them have values, like -D_XOPEN_SOURCE=500. _POSIX_SOURCE doesn't need an argument; it is just defined or not, but _POSIX_C_SOURCE is numeric.
I just checked glibc and Cygwin: on both, _POSIX_SOURCE is enough to reveal the getchar_unlocked declaration. It is quite old, dating back to POSIX.1 1996.
Beware: on some systems, multiple feature selection macros don't play along reasonably; they give you a set intersection rather than union, so that -D_POSIX_SOURCE and -D_BSD_SOURCE together end up meaning "Declare to me only those handful of functions that are specific to classic BSD that have been standardized in POSIX too", which means that next to nothing is declared.

getchar_unlocked is not a C standard function.
Compiling it forcing c99 standard does not support it natively.

Related

GCC options for strict C90 code?

I am trying to find what is the combination of gcc flags to use when testing strict C90 conformance. According to previous post: GCC options for strictest C code?, I should only need a --std=c90.
However here is what I tried:
$ cat t.c
#include <stdint.h> /* added in C99 */
int main()
{
uint64_t t;
return 0;
}
$ gcc -std=c90 -ansi -pedantic t.c
The above does work well (no warnings/errors produced).
Does anyone knows of:
gcc flags to have strict ISO/IEC 9899:1990 conformance
A different compiler (tcc, clang...) with different set of flags ?
EDIT:
Sorry for my wording, yes I would really like to mimic a strictly conforming C90 compiler, in other word it should fail if the code tries to use any feature added later (C99 comes to mind). So pthread include header ought to emit a warning when compiled in what GNU/GCC calls C90 mode (just like stdint.h header should produce a warning without C99). -pedantic nicely warns me about usage of long long, I do not see why it should not warn me about uint64_t.
I used the terminology of ISO/IEC 9899:1990 as quoted from:
http://en.wikipedia.org/wiki/C_(programming_language)#ANSI_C_and_ISO_C
In 1990, the ANSI C standard (with formatting changes) was adopted by
the International Organization for Standardization (ISO) as ISO/IEC
9899:1990, which is sometimes called C90. Therefore, the terms "C89"
and "C90" refer to the same programming language.
EDIT2:
GCC documentation are actually quite clear:
Some features that are part of the C99 standard are accepted as
extensions in C90 mode, and some features that are part of the C11
standard are accepted as extensions in C90 and C99 modes.
So my question is rephrased into:
Is there a compiler + standard include header on a linux system which strictly conforms to C90 ?
C90 compliance doesn't mean that the compiler can't offer other headers that aren't mentioned in the C90 standard. (sys/socket.h, for instance.) If you want to disallow these for some strange reason, you can pass the -I option to add an extra include path, and in that path put versions of all the C99-only headers which are simply #error Don't include me.
Keep in mind here that GCC itself is a conforming freestanding implementation of the C standard specified; such an implementation only supplies a small subset of the standard header files, and practically none of the actual functionality of the C standard library, instead relying on another party -- glibc on Linux systems, for instance -- to supply the C standard library's functionality.
What you seek is something that not only warns you when you are using a C99/C11/GNU language feature that is not in C90, but when you use a library function that is not defined by C90 itself. Sadly, the compiler alone cannot do this for the reason stated above -- it is aloof to what libc it is used with. On glibc systems, the C standard library will pick up on the macros defined by -std=c90 or -ansi:
The macro __STRICT_ANSI__ is predefined when the -ansi option is used. Some header files may notice this macro and refrain from declaring certain functions or defining certain macros that the ISO standard doesn't call for; this is to avoid interfering with any programs that might use these names for other things.
and give you some help by turning off gratuitous extensions:
If you compile your programs using ‘gcc -ansi’, you get only the ISO C library features, unless you explicitly request additional features by defining one or more of the feature macros.
However, this only covers extensions and POSIX-but-not-ISO C functions; it will not save you if a function's behavior is specified differently in ISO C and POSIX.1!

Cannot use standard library function name for a global variable, even when no headers are included

Declaring a global variable with the same name as a standard function produces an error in clang (but not gcc). It is not due to a previous declaration in a header file. I can get the error by compiling the following one-line file:
extern void *memcpy[];
Clang says
foo.c:1:14: error: redefinition of 'memcpy' as different kind of symbol
foo.c:1:14: note: previous definition is here
Apparently this only happens for a few standard functions. printf produces an error, fprintf produces a warning, fseek just works.
Why is this an error? Is there a way to work around it?
Motivation. I am using the C compiler as a compiler backend. C code is programmatically generated. The generated code relies on byte-level address arithmetic and pointer type casting. All external symbols are declared as extern void *variablename[];.
According to the C standard (ISO 9899:1999 section 7.1.3), "all external identifiers defined by the library are reserved in a hosted environment. This means, in effect, that no user-supplied external names may match library names."
Your problem can be easily solved by adding a unique prefix to all your identifiers, e.g. "mylang_".
As an alternative, you can avoid the problem by using the LLVM or GCC -ffreestanding flag, which will compile your code for a non-hosted environment. (The C standard specifies that the restriction only applies to a hosted environment.) In this case you can use all the names you want (apart from main, which is still your program's entry point), but you must make your own arrangements for your library. This is how operating system kernels can legally define their own versions of the C library functions.
The reason is explained here and a relevant extract is given below. http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html
I get an error in gcc as well.
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:
Other people reading your code could get very confused if you were using a function named exit to do something completely different from what the standard exit function does, for example. Preventing this situation helps to make your programs easier to understand and contributes to modularity and maintainability.
It avoids the possibility of a user accidentally redefining a library function that is called by other library functions. If redefinition were allowed, those other functions would not work properly.
It allows the compiler to do whatever special optimizations it pleases on calls to these functions, without the possibility that they may have been redefined by the user. Some library facilities, such as those for dealing with variadic arguments (see Variadic Functions) and non-local exits (see Non-Local Exits), actually require a considerable amount of cooperation on the part of the C compiler, and with respect to the implementation, it might be easier for the compiler to treat these as built-in parts of the language.
The page also describes other restricted names.

Does changing the target C standard achieve anything?

I'm interested in the effects of compiling valid C99 code with a C11 compiler. Is there any practical difference?
As an example, could changing
gcc -c -pedantic -std=c99 source.c
to
gcc -c -pedantic -std=c11 source.c
achieve anything, where source.c is valid C99? Could this introduce regressions, or give optimisations for free?
I'm interested specifically in gcc, although answers addressing other compilers are most welcome.
I used the C11 Wikipedia page as a quick check to see the difference between C99 and C11.
I do notice that gets is removed in C11, so that's one possible regression. The only other one I can see is if the code does something like version detection that's not future-proof, like #if __STDC_VERSION__ == 199901L .
Backwards compatibility is considered very important for the committee that maintains the C standard.
You can expect that a strictly conforming program written according to the preceding standard will function identically when compiled with the settings for the new standard, unless
the program uses a feature that was removed (gets when moving from C99 to C11)
the program uses a feature that was made optional and is not provided by the compiler (e.g. complex types or VLA's)
The latter is unlikely to really hit you, because it is not expected that compilers that had these features will remove them now they are optional. It is more likely that if a compiler in C11 mode doesn't support VLA's, then it also doesn't do so in C99 mode (and will be non-conforming to C99 in that respect).
For programs that aren't strictly conforming (the majority of real programs), you also have to check that the new additions don't interfere with your code. Things to watch out for are:
New standard headers that have the same name as your own headers
Incorrect use of reserved identifiers that have been given a use in the new standard. In particular, identifiers that start with an underscore and a capital letter

Using standard function name in C

I am compiling one program called nauty. This program uses a canonical function name getline which is also part of the standard GNU C library.
Is it possible to tell GCC at compile time to use this program defined function?
One solution:
Now you have declaration of the function in some application .h file something like:
int getline(...); // the custon getline
Change that to:
int application_getline(...); // the custon getline
#define getline application_getline
I think that should do it. It will also fix the .c file where the function is defined, assuming it includes that .h file.
Also, use grep or "find in files" of editor to make sure that every place where that macro takes effect, it will not cause trouble.
Important: in every file, make sure that .h file included after any standard headers which may use getline symbol. You do not want that macro to take effect in those...
Note: this is an ugly hack. Then again, almost everything involving C pre-processor macros can be considered an ugly hack, by some criteria ;). Then again, getting existing incompatible code bases to co-operate and work together is often a case where a hack is acceptable, especially if long term maintenance is not a concern.
Note2: As per this answer and as pointed out in a comment, this is undefined behavior by C standard. Keep this in mind, if intention is to maintain the software for longer then just getting a working executable binary one time. But I added a better solution.
Note that you may trigger undefined behavior if the GCC header where standard getline is defined is actually used in your code. These are the relevant information sources (emphasis mine):
The libc manual:
1.3.3 Reserved Names
The names of all library types, macros, variables and functions that come from the ISO C standard are reserved unconditionally; your program may not redefine these names. All other library names are reserved if your program explicitly includes the header file that defines or declares them. There are several reasons for these restrictions:
[...]
and the C99 draft standard (N1256):
7.1.3 Reserved identifiers
1
Each header declares or defines all identifiers listed in its associated subclause, and
optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.
[...]
2
No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
3
If the program removes (with #undef) any macro definition of an identifier in the first
group listed above, the behavior is undefined.
Thus even the macro trick suggested in another post will invoke undefined behavior if you include the header of getline in your code.
Unfortunately, in this case the only safe bet is to manually rename all getline invocations.
C demands unique function names.
but you can use -fno-builtin or -ffreestanding gcc flags.
see description about this flags in gcc man page.
A common approach is to use prefixes which form some sort of namespace. Sometimes you can see macros used for this to make changing the namespace name easier, e.g.
#define MYAPP(f) myapp_##f
Which is then used like
int MYAPP(add)(int a, int b) {
return a + b;
}
This defines a function myapp_add which you can also invoke like
MYAPP(add)(3, 5);
This standards compliance issue started to bug me, so I did a bit of experimenting. Here's a 2nd answer, which is possibly better then the currently accepted answer of mine.
First, solution:
Just define macro _XOPEN_SOURCE with value 699, by adding this to compiler command line options
-D_XOPEN_SOURCE=699
How exactly, that depends on applications build system, but one probably working way would be to define CFLAGS environment variable, and see if it takes effect when rebuilding:
export CFLAGS="-D_XOPEN_SOURCE=699"
Other alternative would be to add #define _XOPEN_SOURCE 699 before includes in every .c file of the application, in case it uses some esoteric build system and you can't get it added to compile options, but doing it from command line is by far preferable.
Then some explanation:
Man page of getline specifies, that getline is defined only under certain standards, such as if _XOPEN_SOURCE>=700. So, by defining a smaller value before including the relevant file, we exclude the library declaration. More information about these feature-test macros is found in GNU libc manual.
I expected there to be some linker issues too, but there weren't, and my investigation resulted this question here. To summarize, linker will prefer symbol from linked object files (at least with gcc), and will only look at dynamic libraries if it has not found symbol otherwise. So, since getline is not ISO C symbol, GNU libc documentation quoted in this answer seems to imply, that after using the _XOPEN_SOURCE trick of this answer, it's ok to use it in an application. Still, beware of other libraries using the POSIX getline and ending up calling application's function (probably with different parameters, resulting in undefined behaviour, probably a crash).
Here is a neat solution to your problem. The trick is LD_PRELOAD.
I have done the similar thing in one of my question post.See the following.
Hack the standard function in library and call the native library function afterwards
You can defined the getline() in the separate file. This will make the design clean too. Now, compile that c file;
$gcc -c -g -fPIC <file.c>.
This will create the file.o. Now, make the shared object of it.
-g for debugging.
-fPIC for position independent code. This will help to save the RAM SIZE. The text segment will be shared, if you specify the -fPIC option.
$gcc -shared libfile.so file.o
Now, link your main file with this shared object.
gcc -g main.c -o main.out -lfile
while executing, use the LD_PRELOAD, this will use your library instead of the native API.
$LD_PRELOAD=<path to libfile.so>/libfile.so ./main.out
If you like my answer,then please appreciate. I have done the similar kind of stuff, in my previous post Hack the standard function in library and call the native library function afterwards .

MinGW compiler doesn't need function declarations?

I have these two files:
// first.c
int main(void) {
putint(3);
}
and
// second.c
#include <stdio.h>
void putint(int n) {
printf("%d",n);
getchar();
}
When I run gcc 4.6.1 under Win XP:
gcc first.c second.c -o program.exe
It has no problem and writes 3 to stdout. It doesn't need putint declaration in first.c. How is this possible? Is this standard behavior?
I have tested this on MSVC 2008 Express and it runs only with the declaration as expected.
// first.c
void putint(int);
int main(void) {
putint(3);
}
Solved, thanks for hints, these options helped to show the warning:
-Wimplicit
-std=c99 (MinGW 4.6 still uses gnu90 by default)
This is a legacy "feature" of C that should not be used as of several decades ago. You should use a compiler with settings that will warn you if you do something like this. Gcc has several switches that you should specify when using it & one of them will give you a warning for this.
Edit: I haven't been using gcc myself, but switches that you should check out are -pedantic, -Wall, -Wextra, and -std.
The compiler that is accepting this is assuming, per the old language definition, that since you didn't see fit to tell it otherwise, the function a) returns an int value and b) since you pass it an int (or if you passed it something that could be promoted to an int) the function expects that argument to be an int.
As #veer correctly points out, this should generally work in your particular case. In other cases, however, differences between the implicit assumptions for a function without a prototype and the function's actual signature would make things go boom.
This isn't just for MinGW, but all standard versions of gcc. As noted, this is legal in C89; gcc defaults to 'gnu89' (not 99), which also accepts the code without warning. If you switch to c99 or gnu99 (or later, such as c11) you'll get a warning by default, but it will still compile.
As is noted by others, this is standard behavior for C conforming compilers. Naming your files .c partially puts it in C mode. It'll have fun things like "built-in functions" (printf() etc.) and all sorts of legacy C things.
I'd like to add to what others have said that I experienced recently, though. MS expressly dropped support for C past C90, and their C90 support is poor to say the least. I'm not entirely sure standard ANSI C90 codebases would compile under newer VS's, because it is basically the C++ compiler with lots of stuff disabled (whereas GCC actually has a C compiler). They did this in order to promote C++. If you want to use real C, you can't really do it in MS Visual Studio, any edition, unless you want to be declaring all your variables at the start of functions, etc.

Resources