(Where) Does clang document implementation-defined behavior? - c

Implementation-defined behaviors in C are unspecified behaviors for which each conforming implementation must document its choice.
I found such documentations easily for gcc here or Microsoft C here, but I can't find any such documentation for clang.
Am I searching wrong or is there no such thing?

This ticket https://github.com/llvm/llvm-project/issues/11644 is still opened (for many years now) so it seems that clang doesn't explicitly specify implementation defined behaviour.
For most cases I would bet that it's the same as GCC, though.

Related

Does "the" C standard specify which standard a compiler has to adhere to?

I just tried to compile a C program with a GNU compiler version 4.9.2. The source code contained a few for int i=0; ... statements and the compiler gave me an error and indicated that I should use -std=c99 in order to compile for loop initial declarations. Apparently, such declarations were not valid before C99.
On an another machine, I have a more recent GNU compiler (8.1.1) where I can compile the same source code without explicitly specifying -std=c99.
Because GNU obviously made their compiler C99 compliant between 4.9.2 and 8.1.1, this lead me to the question if a recent C standard specified that a compiler has to adhere to C99 (or another standard).
Choosing whether to adhere to the C standard, or a particular version of it, is voluntary. The choice does not come from the C standard. It comes from outside. Anybody who makes a C implementation decides whether to conform to the 2018 C standard (or to conform mostly but not completely), whether to conform to the 2011 C standard, whether to conform to some “K&R” notion of C, or something else. Nothing in the C standard says, well, if you are conforming to this standard, your compiler has to conform to some previous version. The standard cannot actually require you to do anything until you choose to conform to the standard.
The C standard and the people who make it and the standards organizations that endorse and publish it have little power to make anybody do anything. They cannot publish the C standard and say you, René Nyffenegger, must obey the 2018 C standard. They are not law-making bodies. There are contracts between private parties which say some project will be produced in accordance to this standard or that standard, but those are private agreements, not public law.
In the 2018 C standard, paragraph 8 of the Foreword says:
For an explanation of the voluntary nature of standards, the meaning of ISO specific terms and expressions related to conformity assessment, as well as information about ISO’s adherence to the World Trade Organization (WTO) principles in the Technical Barriers to Trade (TBT), see the following URL: www.iso.org/iso/foreword.html.
Nor can the standard organizations prohibit you from writing a C compiler that does or does not conform to any particular version of the standard, nor from writing a compiler that conforms largely but not completely.
If you use the name of the C standard commercially, perhaps by claiming conformance to it, the standards organizations might have some legal rights in that regard. That involves international law and the law of many jurisdictions, which I cannot speak to authoritatively. I have not heard of any problems occurring from somebody claiming to conform to the C standard.
The standards organizations do officially withdraw old versions of the standards when a new version is published. This does not prevent you from writing a C implementation that conforms to an old version, but it would prevent you from claiming you are conforming to the current version when you are not. (For example, if a contract you agreed to required you to conform to the current C standard, that would change when the organization publishes a new version and withdraws the old one.)
Prior to GCC 5.0, the default standard it adhered (most closely) to was the C90 standard — specifying no standard was equivalent to specifying -std=gnu90.
From 5.0 onwards, the default was changed to the C11 standard — so specifying no standard was equivalent to specifying -std=gnu11.
Your two compiler versions show this behaviour.
Note that the C standard only prescribes what a compiler must do to adhere to that standard. It does not mandate the behaviour of a compiler with respect to previous or future versions of the standard; there is only one version of the standard as far as the standard is concerned. What compiler implementations do about other versions is entirely up to the compiler writers.
You can, of course, override the default behaviour of GCC with an explicit version:
-ansi
-std=c90
-std=c99
-std=c11
-std=gnu90
-std=gnu99
-std=gnu11
… and some other variations …
The -ansi option is equivalent to -std=c90. The difference between the -std=cXX and -std=gnuXX is that the c version doesn't set the macros for various extensions, so you might have to explicitly indicate that you want to use POSIX interfaces, for example, with options such as -D_XOPEN_SOURCE=700, whereas with gnu version sets those macros automatically.
The each version of the C Standard classifies implementations into two categories: those which comply with that particular version of the Standard, and those that don't. There aren't any C Language Police who will break the kneecaps of anyone who sells non-conforming implementation. Indeed, there are some situations where a non-conforming implementation would be more useful than any conforming implementation could be (e.g. on some small embedded platforms, the amount of code required to produce a full conforming implementation of "printf" might exceed the total code space available). Further, there is no guarantee that a every conforming implementation will be suitable for any particular purpose (indeed, it would be possible to contrive a C implementation which was unsuitable for any purpose whatsoever except to demonstrate that the C Standard doesn't mandate usefulness).
Most quality C development systems can be invoked in different modes which may conform (or fail to conform) with different versions of the Standard, and may be suitable (or unsuitable) for various purposes. From the point of view of the Standard, every different mode in which a development system can be invoked would be a different implementation. I think it would be useful to have the Standard to sub-categorize implementations based upon their support (or lack thereof) for popular features or guarantees that would make them suitable (or unsuitable) for common purposes (e.g. low-level or systems programming) but as yet the Standard has not done so.

C standard prohibition on warnings by default

Seeing yet another question the answer to which would have been obvious had the questioner compiled with -Wall got me thinking.
Is there a 'C standard' based reason why -Wall cannot be enabled by default by the compiler?
As far as I know none of the major compilers do this (and certainly historically none of them did it), and I'd like to know whether this is adherence to the standard, or some other reason (inertia, back compatibility or whatever). Speculating as to the other reason is probably off-topic (opinion based), but I think asking whether a standard requires this behaviour is on-topic (factual).
Quoted from N1570 Annex I:
1 An implementation may generate warnings in many situations, none of
which are specified as part of this International Standard.
This implies that warnings are non-compulsory to compilers, so I don't think there would be any "C standard" based reasons.
Is there a 'C standard' based reason why -Wall cannot be enabled by default by the compiler?
I think that the answer to that is that no standard-based reason. The behavior of compiler switches is outside the scope of a language standard.
Beyond that, a compiler is (generally speaking) not required to produce diagnostics for things that are not specified to be compilation errors, so requiring such diagnostics be output "by default" is nonsensical.
And to be clear, these general statements apply in the case of the C language.
Besides the reason mentioned above, that the standard does not have specifications on warnings, make Wall default would be more a obstacle for many people because there are warnings that you actually don't want to turn on from time to time, such as warnings on unused variables/functions etc.
If you want to make it "by default", you can alias the compiler of your choice, take gcc as example, add following in your bashrc:
alias gcc="gcc -Wall"

Does GCC atomic buitlins work with std=C99?

I am using this built-in atomic methods link
It is mentioned that:
The following built-in functions approximately match the requirements
for the C++11 memory model.
However I have tried compiling these methods with std=C99 and std=C89. The program compiles and I get the right results. Is there something I am missing here ?
Does C99 and C89 have a memory model as well ?
It is a compiler extension and therefore it is allowed to provide functionality outside of the what the standard allows but that page does not make it obvious that is the can be used in C.
Fortunately, gcc does have good online documents and if we check out for example the 4.9 series document on C extensions the __atomic Builtins points to the same page.
So that would indicate that it is valid to use in C and it will stick the requirements as laid out in the documentation and so it will work in the C99 as it does in C++. Usually if there is a difference between how a feature/extension is implemented between C and C++ the documents will note this, for example compound literals have significant differences.

How to check C source code against the current standard?

I'm continuing to learn C and would like to adhere to whatever is the current standard, but finding a good reference to that seems to be problem.
From what I've found online (mostly through Google and Wikipedia) is that the current standard used today is C99, more formally the ISO/IEC 9899:1999 standard.
When I'm writing C code, I often bring up a browser and do simple web searches for things like finding out the exact return values to the stdio.h function scanf. Mostly I just want to get into a good practice of adhering to the current standard, but even if I search for the specific string "C99 printf" or something like it, there doesn't seem to be one single place to find a definitive spec.
So I have two questions:
1) Is there a central C99 spec that is available online, maintained by the organization responsible for this standard?
[edit]: This first question has already been answered here: Where do I find the current C or C++ standard documents?. Thanks to James McNellis for pointing this out.
2) Is there a program that can parse a C source file to make sure it adheres to the C99 spec? I know there are programs like this to parse XHTML files and it seems like there should be one for C99 as well...
[edit]:
I should also mention that I'm doing C development using gcc, specifically version 3.4.4.
When I go to the main gcc website (http://gcc.gnu.org/) I'm still running into difficulty figuring out which compiler version supports which C specification.
The current standard for Programming
Language C is ISO/IEC 9899:1999,
published 1999-12-01
and
Published ISO and IEC standards can be
purchased from a member body of ISO or
IEC.
From your bestest buds in the standards world, ISO.
It's also worth noting the draft of the NEXT C standard is available in PDF.
Depending on what compiler you use you can ask it to check for you. For example with gcc you would run it like this:
gcc -Wall -Wextra -pedantic -std=c99 -o program program.c
You would replace program.c and program with the name of your program of course.
-Wall and -Wextra provide more warnings and tell you if you have done something funky. -pedantic provides more of that as well.
you can use -ansi if you really want to follow the ansi spec personally I don't use it since I'm lazy but it is more proper.
It is not actually possible to analyse a source file and conclusively determine that it complies with the C99 standard. C is different to XHTML in this regard, because C is a Turing-complete language and XHTML is not.
It is certainly possible to find many instances of non-conformance, but it's impossible to find them all. Consider, for example, a program that generates a printf format string on-the-fly - how can you statically determine that the format string will be conforming? What if it depends on the input given to the program? Consider also a program that right shifts signed integers - if the signed integer in question is never negative, then the program may be conforming, but if not then it is probably relying on implementation-defined results.
The draft for can be obtained here for free. You can also purchase the official one from the ansi store.

What is the state of C99 support in major compilers / toolchains?

A response to a comment I made here made me stop and think: "I don't really know what the state of C99 support is."
Wikipedia gives details for a few compilers, but I'm not familiar enough with C99 to know all the bits and pieces of the standard, so I'm looking for a gestalt overview answer to the question:
What is the state of C99 support in major compilers / toolchains?
MSVC: Intentionally not implemented unless it overlaps with C++
GCC: Most of the useful parts are in (and have been for awhile). Some missing features.
clang: Claims full C99 support

Resources