I was curious if this is intentional. I found that traditionally __STDC_IEC_559__ is defined in glibc and then used by gcc. Cygwin doesn't use glibc however, and I was wondering if __STDC_IEC_559__ isn't defined by newlib for whatever reason or if it is merely a problem on my end.
I understand that all compilers/libraries do not define __STDC_IEC_559__ as they are not all compliant with the standard, I am just trying to figure out why the libraries used by cygwin specifically are not.
Related
When working with strdup on Windows I found out that _strdup is Windows specific, but when I ran the same code on Linux it required strdup without the underscore. Does anyone know the history behind this difference, as-well as some information on how you have dealt with this problem when writing cross-platform code?
There are several functions that are part of the POSIX specification, i.e. Linux and most other UNIX variants, that are not part of standard C. These include strdup, write, read, and others.
The reasoning for the leading underscore is as follows, taken from the MSDN docs:
The Universal C Run-Time Library (UCRT) supports most of the C
standard library required for C++ conformance. It implements the C99
(ISO/IEC 9899:1999) library, with certain exceptions: The type-generic
macros defined in , and strict type compatibility in
. The UCRT also implements a large subset of the POSIX.1
(ISO/IEC 9945-1:1996, the POSIX System Application Program Interface)
C library. However, it's not fully conformant to any specific POSIX
standard. The UCRT also implements several Microsoft-specific
functions and macros that aren't part of a standard.
Functions specific to the Microsoft implementation of Visual C++ are
found in the vcruntime library. Many of these functions are for
internal use and can't be called by user code. Some are documented for
use in debugging and implementation compatibility.
The C++ standard reserves names that begin with an underscore in the
global namespace to the implementation. Both the POSIX functions and
Microsoft-specific runtime library functions are in the global
namespace, but aren't part of the standard C runtime library. That's
why the preferred Microsoft implementations of these functions have a
leading underscore. For portability, the UCRT also supports the
default names, but the Microsoft C++ compiler issues a deprecation
warning when code that uses them is compiled. Only the default names
are deprecated, not the functions themselves. To suppress the warning,
define _CRT_NONSTDC_NO_WARNINGS before including any headers in code
that uses the original POSIX names.
I've handled that by having a #define that check if the program is being compiled for Windows, and if so create another #define to map the POSIX name to the Windows specific name. There are a few choices you can check, although probably the most reliable is _MSC_VER which is defined if MSVC is the compiler.
#ifdef _MSC_VER
#define strdup(p) _strdup(p)
#endif
Is there any way to access thread.h file .
I am not able to find thread.h header in windows since threading is related to OS.
I tried using pthread.h an external library , but was never able to find thread.h which according to my professor works in solaris.
This is an excellent example where tagging a question with "C" and "C++" is highly confusing because the answers are entirely different.
If you are coding in C++11 or later, then you should
#include <thread>
and use the std::thread class. You'll be fine.
If you are coding in C11 or later, then you should
#include <threads.h>
However, you may have to wait until your implementation supports it. § 7.26.1 ¶ 2 of the C11 standard says:
Implementations that define the macro __STDC_NO_THREADS__ need not provide this header nor support any of its facilities.
You can check with an #ifdef whether your implementation defines it. At least my GCC does.
For the time being, if you cannot switch to C++, use a third-party threading library like pthreads.
thread.h isn't well defined in the context of c++ standards. If you have a c++11 compliant toolchain, you need to
#include <thread>
as stated in the reference documentation.
Pre standard toolchains probably need to have the standard specified explicitly using the -std=c++0x or -std=c++11 compiler flags.
As you changed your focus to c, including c++ headers won't work. You may try pthread.h.
C99 added a macro __STDC_IEC_559__ which can be used to test if a compiler and standard library conform to the ISO/IEC/IEEE 60559 (or IEEE 754) standard.
According to the answers for this question
how-to-check-that-ieee-754-single-precision-32-bit-floating-point-representation most C compilers don't set the preprocessor macro __STDC_IEC_559__.
According to GCC's documentation it does not define __STDC_IEC_559__.
I tested this with GCC 4.9.2 and Clang 3.6.0 both using with glibc 2.21 using the following code.
//test.c
//#include <features.h>
int main(void) {
#if defined ( __STDC_IEC_559__ )
//#if defined ( __GCC_IEC_559__ )
return 1;
#else
return 0;
#endif
}
and then
echo $?
This shows that with this code __STDC_IEC_559__ is defined with GCC but not with Clang. I then did gcc -E and it showed that the file stdc-predef.h is included. This file defines __STDC_IEC_559__.
/* glibc's intent is to support the IEC 559 math functionality, real
and complex. If the GCC (4.9 and later) predefined macros
specifying compiler intent are available, use them to determine
whether the overall intent is to support these features; otherwise,
presume an older compiler has intent to support these features and
define these macros by default. */
#ifdef __GCC_IEC_559
# if __GCC_IEC_559 > 0
# define __STDC_IEC_559__ 1
# endif
#else
# define __STDC_IEC_559__ 1
#endif
This confirms that it's glibc that defines this macro and not GCC.
However, when I include features.h (or stdio.h) this file is included by Clang as well and that __STDC_IEC_559__ is defined.
So __STDC_IEC_559__ is defined by both GCC and Clang (with a glibc header file) which seems to disagree with the answer to the first question I linked to.
I then tested musl (e.g. musl-gcc -test.c) which is a different standard library than glibc. This showed that __STDC_IEC_559__ is not defined with musl.
As I understand it the standard C library does not define the basic floating point algebra. For example the standard C library does not define the result of 1.0/-0.0. This is defined by the compiler.
My questions are (ranked in order of importance to me):
Why is __STDC_IEC_559__ defined by glibc and not by the compiler?
If I made my own standard library and I wanted to define __STDC_IEC_559__ I would need to know that the compiler already conforms to IEEE 754 for operations not defined in my standard library (e.g 1.0/-0.0). Is there documentations for this or a macro to test for this?
Wikipedia states that "users should be aware that this macro (__STDC_IEC_559__) is sometimes defined while it shouldn't be". Is this statement still accurate?
I believe __STDC_IEC_559__ relies on some library features and can't be defined solely by the compiler. See this post for some information. This is not uncommon for C -- the compiler and the C library must sometimes cooperate in order to implement the entire standard.
What you're asking depends on the compiler. I think you would have to have special knowledge of the compiler in order to decide this. In the specific case of GCC, it defines a macro to tell you. Search this node of the manual for __GCC_IEC_559.
Well... I don't know the answer to this one :-). The original post seems to indicate that, yes, GCC might define __GCC_IEC_559 if it intends to implement IEEE 754, even if it does not actually do so.
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!
I use dev c++ for my c projects,because it's simple for me.I installed it with the mingw extension.Well,I included stdlib.h and made a call to mrand which according to manpages belongs to that header but I got a linker error.I looked in mingw's headers and found no declaration for mrand although the glibc has one in stdlib.Am I missing something?I thought mingw and gcc were the same.If they are different I suppose that there isn't a way to get gcc's full power.Right?Thank you.
mrand is not part of the standard C library, nor is it present in standard Linux manpages. Whatever compiler you previously used may have had it as a proprietary extension, but since you haven't mentioned which (it's not GCC or MSVC, at least), I can't tell what mrand is supposed to do, and so it's hard to suggest an alternative function to use.
Note that glibc does offer a mrand48(). Since this is a POSIX function, not a standard C function, it may or may not be present in other C libraries - but note that this is a function of the C library (glibc), not the compiler (gcc/mingw).