Glibc - error in ucontext.h, but only with -std=c11 - c

I have this minimal helloworld, extended with an include of ucontext.h:
#include <ucontext.h>
#include <stdio.h>
int main(int argc, char** argv) {
printf ("hello world!\n");
return 0;
}
It compiles without warning with gcc-4.9 (gcc -c hw.c -Wall).
But if I switch to the c11 standard (gcc -std=c11 -c hw.c -Wall), I get the following error:
$ gcc -std=c11 -c hw.c -Wall
In file included from /usr/include/ucontext.h:26:0,
from hw.c:1:
/usr/include/x86_64-linux-gnu/sys/ucontext.h:137:5: error: unknown type name ‘stack_t’
stack_t uc_stack;
^
My first idea is that glibc doesn't support c11. Googling for that didn't reveal usable information. What is the case?
(I use glibc-2.19 with gcc-4.9. It is a debian jessie, amd64.)

-std=c11 is C11 standard compliant mode. <ucontext.h> isn't strictly part of C11 (see Stas's answer).
To use these headers either use extension mode -std=gnu11 or define appropriate macro depending on which platform do you intend to support (_POSIX_C_SOURCE, _BSD_SOURCE, _XOPEN_SOURCE, _GNU_SOURCE or maybe others).
See this page for more info about feature-enabling macros.

It seems <ucontext.h> functions are deprecated, because they use deprecated C feature. So they can't be used in standard compliant C code. See the rationale:
With the incorporation of the ISO/IEC 9899:1999 standard into this
specification it was found that the ISO C standard (Subclause 6.11.6)
specifies that the use of function declarators with empty parentheses
is an obsolescent feature. Therefore, using the function prototype:
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
is making use of an obsolescent feature of the ISO C standard.
Therefore, a strictly conforming POSIX application cannot use this
form. Therefore, use of getcontext(), makecontext(), and swapcontext()
is marked obsolescent.
So, it is not directly related to C11. For example, I can't compile your example with clang on Mac OS X at all.
It was deprecated in C99 standard:
6.11.6 Function declarators
The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an
obsolescent feature.

Related

Why gcc gives warning: implicit declaration of function qsort_r?

I do include<stdlib.h> where qsort_r is given. And I use gcc -std=c99 -O3 myfun.c -o myfun to compile.
It compiles, links and runs well. I don't know why I got this warning and what is potential risk of this warning ?
BTW, my compiler is gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-1ubuntu1)
It does so because you use -std=c99 , there's no qsort_r function in stdlib.h in c99.
Use -std=gnu99 to make the extensions available, or add a #define _GNU_SOURCE to your source files before including the header files.
qsort_r is not supported by C99. Specification says nothing about it.
Language Standards Supported by GCC:
By default, GCC provides some extensions to the C language that on rare occasions conflict with the C standard1. See Extensions to the C Language Family. Use of the -std options listed above will disable these extensions where they conflict with the C standard version selected. You may also select an extended version of the C language explicitly with -std=gnu89 (for C89 with GNU extensions) or -std=gnu99 (for C99 with GNU extensions). The default, if no C language dialect options are given, is -std=gnu89; this will change to -std=gnu99 in some future release when the C99 support is complete. Some features that are part of the C99 standard are accepted as extensions in C89 mode.
1. Emphasis is mine

Compiling error when -std=gnu99 and inline function is used

The following code:
#include <stdio.h>
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
does not compile when I use the -std=gnu99 flag (I am compiling with gcc). This is the error it throws:
gcc -std=gnu99 -c main.c -o main.o
gcc -std=gnu99 main.o -o main
main.o: In function `main':
main.c:(.text+0x15): undefined reference to `myfunc'
collect2: ld returned 1 exit status
make: *** [main] Error 1
The compilation goes with no problems when -std=gnu99 is omitted. Does anyone know why is the linker complaining if -std=gnu99 is used?
In C99 you need to specify either a declaration to your inline function like
int myfunc(int);
or allow the compiler to actually inline the function by specifying -finline-functions or -O3.
Quoting the C99 standard:
Any function with internal linkage can be an inline function. For
a function with external linkage, the following restrictions
apply: If a function is declared with an inline function specifier,
then it shall also be defined in the same translation unit. If
all of the file scope declarations for a function in a translation
unit include the inline function specifier without extern, then
the definition in that translation unit is an inline definition. An
inline definition does not provide an external definition for the
function, and does not forbid an external definition in another
translation unit. An inline definition provides an alternative to an
external definition, which a translator may use to implement any
call to the function in the same translation unit. It is
unspecified whether a call to the function uses the inline
definition or the external definition.
So the compiler is free to use the external definition of myfunc - which doesn't exist if you don't provide it, hence the linker error. Why does it prefer to choose a non existing external definition? Because you disallowed inlining by not using -finline-functions or a optimization level which contains this flag.
This is the gnu_inline hiccup. Use -std=gnu99 -fgnu89-inline.
For more information see Function Attributes (item gnu_inline).
The relevant passage:
In C, if the function is neither extern nor static, then the function is compiled as a standalone function, as well as being inlined where possible.
This is how GCC traditionally handled functions declared inline. Since ISO C99 specifies a different semantics for inline, this function attribute is provided as a transition measure and as a useful feature in its own right. This attribute is available in GCC 4.1.3 and later. It is available if either of the preprocessor macros GNUC_GNU_INLINE or GNUC_STDC_INLINE are defined. See An Inline Function is As Fast As a Macro.
You should declare 'myfunc' before define it.
For example this code can be compiled with -std=gnu99 option:
#include <stdio.h>
int myfunc(int);
inline int myfunc (int x) {
return x+3;
}
int main () {
printf("%d", myfunc(2));
return 0;
}
UPDATED
Actually, regarding to the C standard inline keyword is just a suggestion to the C compiler. But compiler can choose not to inline. So it can do its own way, therefore.
In your example you can use function declaration as I showed above - or you can add optimization flag '-O3' (tested on linux gcc) and above - in this case your source code will compiled without extra-declaration.
UPDATED
Here you can find deeper explanation: https://blogs.oracle.com/dew/entry/c99_inline_function
Apparently you need to specify that you are using and you want to adopt inline functions
-fgnu89-inline
The option -fgnu89-inline tells GCC to use the traditional GNU semantics for "inline" functions when in C99 mode. This option is
accepted and ignored by GCC versions 4.1.3 up to but not including
4.3. In GCC versions 4.3 and later it changes the behavior of GCC in C99 mode. Using this option is roughly equivalent to adding the
"gnu_inline" function attribute to all inline functions.
The option -fno-gnu89-inline explicitly tells GCC to use the C99 semantics for "inline" when in C99 or gnu99 mode (i.e., it
specifies the default behavior). This option was first supported in
GCC 4.3. This option is not supported in C89 or gnu89 mode.
The preprocessor macros __GNUC_GNU_INLINE__ and __GNUC_STDC_INLINE__ may be used to check which semantics are in
effect for "inline" functions.
Source: http://linux.die.net/man/1/gcc
So to compile your code you need at least this:
gcc source.c -std=gnu99 -fgnu89-inline

Does ANSI-C not know the inline keyword?

When compiling something as simple as
inline int test() { return 3; }
int main()
{
test();
return 0;
}
with gcc -c test.c, everything goes fine. If the -ansi keyword added, gcc -ansi -c test.c, one gets the error message
test.c:1:8: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int’
This is true even if the C99 standard is explicitly selected, gcc -std=c99 -ansi -c test.c.
What is the reason for this, and is there a recommended fix?
You need to use:
gcc -std=c99 -c test.c
The -ansi flag specifies c90:
The -ansi option is equivalent to -std=c90.
ANSI C was effectively the 1990 version of C, which didn't include the inline keyword.
Nope, ANSI C doesn't have inline.
Your second command actually overrides -std=c99 with -ansi (they both affect -std=), so you are in effect compiling using ANSI C (no C99).
The inline keyword is not part of the original ANSI C standard
(C89) so the library does not export any inline function definitions
by default. Inline functions were introduced officially in the newer
C99 standard but most C89 compilers have also included inline as an
extension for a long time.
quoted from Gnu website
The reason it works fine without the ansi option at all is because gcc defaults to '-std=gnu90', which is ANSI/C89 plus extensions (one of which, not surprisingly, is support for inline functions). If you just want ANSI C support you don't need any options, unless you want strict standard compliance (which obviously may be useful if your code is going to be compiled on other compilers).

gcc - pedantic wont compile, ISO C90 forbids mixed declarations and code How to fix this?

I need that code for my program to have colors. But it wont compile if i use -pedantic. Is there a way around this? its btw
gcc -pedantic MP1.c -o hahah
MP1.c: In function `main':
MP1.c:65: warning: ISO C90 forbids mixed declarations and code
MP1.c:686:30: warning: (this will be reported only once per input file)
line 65:
int originalAttrs = ConsoleInfo.wAttributes;
Move declaration of originalAttrs to the top of the scope in which it is used. The error is unrelated to use of ConsoleInfo.wAttributes but to the location of the declaration of originalAttrs. Without seeing the entire code, it is probably something like:
printf("hello\n"); /* For example. */
int originalAttrs = ConsoleInfo.wAttributes;
To fix:
int originalAttrs;
printf("hello\n"); /* For example. */
originalAttrs = ConsoleInfo.wAttributes;
Either fix the code so it complies with the C90 standard (as hmjd's answer suggests), or tell gcc to use a newer version of the standard.
C does permit mixed declarations and statements starting with the C99 standard.
If you use
gcc -std=c99 -pedantic
or
gcc -std=c11 -pedantic
it should work.

Why does gcc report "implicit declaration of function ‘round’"?

I have the following C code:
#include <math.h>
int main(int argc, char ** argv)
{
double mydouble = 100.0;
double whatever = round(mydouble);
return (int) whatever;
}
When I compile this, I get the warnings:
round_test.c: In function ‘main’:
round_test.c:6: warning: implicit declaration of function ‘round’
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’
I'm rusty with C, but I thought that the #include brought a declaration for round() into scope. I've checked my ANSI standard (C99 is the only copy I have) which confirms that the round() function exists in the math.h header. What am I missing here?
Edit: The compiler is GCC 4.3.2 on Ubuntu (intrepid, IIRC). Running gcc -E gives:
$ gcc -E round_test.c | grep round
# 1 "round_test.c"
# 1 "round_test.c"
# 2 "round_test.c" 2
double whatever = round(mydouble);
so the definition obviously isn't being found in the headers.
I see you're using gcc.
By default, gcc uses a standard similar to C89. You may want to "force" it to use the C99 standard (the parts it complies with)
gcc -std=c99 -pedantic ...
Quote from GCC Manual
By default, GCC provides some
extensions to the C language that on
rare occasions conflict with the C
standard. See Extensions to the C
Language Family. Use of the -std
options listed above will disable
these extensions where they conflict
with the C standard version selected.
You may also select an extended
version of the C language explicitly
with -std=gnu89 (for C89 with GNU
extensions) or -std=gnu99 (for C99
with GNU extensions). The default, if
no C language dialect options are
given, is -std=gnu89; this will change
to -std=gnu99 in some future release
when the C99 support is complete. Some
features that are part of the C99
standard are accepted as extensions in
C89 mode.
Something must be wrong with your gcc installation, system headers, or compilation options.
Try compiling with -E. That will show you what the preprocessor output -- including which headers are being included and what's in them. On my Ubuntu Linux system it's about 1000 lines of output, including this:
extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__));
You need to tell gcc that you want C99, and that you want to link in libm:
gcc -std=c99 -lm round_test.c
The code you type compiles cleanly on MacOS X 10.5.8 with GCC 4.0.1. If prodded with options '-Wall -Wextra', it complains about unused parameters argc and argv - not material.
Have you looked in <math.h> on your machine?
Have you tried with options such as '-stc=c99'?
C99 was the answer, but the full story is a little more complicated. The reason I'd been playing with this at all was that I was trying to compile a library written for Windows, which had its own "optimised" definition of round(). I got a linker error telling me that the definition conflicted with the built-in, so I removed the definition (and declaration). Once I'd done that I started to get the "implicit declaration error".
It seems that the default compile mode (without the -std=c99 flag) is neither conforming C89 nor C99: if it were conforming C89, you should be able to provide a custom definition of round() without conflicting, and if it were conforming C99 the declaration should be in math.h.
you need to link with the math library. So when you compile, be sure to add the -lm flag.

Resources