I have been worked on M3 circuit and wrote some simple code including identifier "uint".
I got an error saying Fatal Error[Pe1696]: cannot open source file "stdint.h".
Do I have to add the source file by myself or is there any way to solve this??
stdint.h was added to C with the year 1999 version of the standard, known as "C99". To use it, you need a compiler that supports C99 or later. Some compilers support it, but it is not enabled per default. This appears to be the case here.
The latest version of IAR supports the current standard C11, and thereby also the previous standard C99. See this link: https://www.iar.com/support/resources/articles/exploring-c11-and-c14/
Click on "C11".
Related
I'm trying to work with some legacy C89 code, and am having trouble getting it to build. My usual environment is Visual Studio, but that only seems to support C99, and some C99 features (such as stdio etc. not necessarily being constant) break the code - a lot. Before I start tampering with the code I want to write some tests, so I don't break the old behaviour, but I can't test the tests, so to speak, before I can get the code to build.
So is there still any way to compile C89 code on Windows?
Edit: Steve Summit has identified that stdio and so on has never been guaranteed; it's just a feature of some compilers that my legacy code happens to depend on, in a rather deeply embedded way. So my question shifts to whether there is any Windows C compiler available (preferably free!) for Windows that supports that assumption. Alternatively, I have an Ubuntu installation in a virtual machine, although I have little experience using it - is there such a compiler available in Ubuntu?
MSVC is a C++ compiler and has just gained C99 support recently. Previously it supports only C89 with some MS extensions. To compile in strict C89 mode use the /Za option. Make sure to also enable /Tc to use C mode
/Za, /Ze (Disable Language Extensions)
The /Za compiler option disables and emits errors for Microsoft extensions to C that aren't compatible with ANSI C89/ISO C90. The deprecated /Ze compiler option enables Microsoft extensions. Microsoft extensions are enabled by default.
See Enforce ANSI C Standard in Visual Studio 2015
Most other compilers use other options like -ansi, -std=c90 or -std=iso9899:1990
However if this is just about stdin/stdout not being constant while using in a static initializer list then it's completely irrelevant to C89 and is actually an XY problem. The following snippet compiles without problem in VS2019 C++ mode, so if you don't have any possible conflict just compile the code in C++ mode
#include <stdio.h>
FILE* ifp = stdout;
int main()
{
fprintf(ifp, "test\n");
return 0;
}
Otherwise it's easy to fix that to compile in C mode by moving the initialization into main()
FILE* ifp = NULL;
int main()
{
ifp = stdout;
fprintf(ifp, "test\n");
return 0;
}
[This isn't really an answer, but it's too elaborate for a comment.]
If you've got code that does things like
#include <stdio.h>
FILE *ifp = stdin;
int main() { ... }
and if the problem you're having is errors stating that stdin is not a compile-time constant suitable for a static initializer, I think you're going to have to rewrite that aspect of your code. I could be wrong, but if I remember correctly, the idea that stdin et al. were compile-time constants was never a guarantee, just a useful property of the earliest Unix implementations. It wasn't necessarily true of all old implementations, so the "change" to the Standard that explicitly said they weren't necessarily constant wasn't a change per se, but rather, more or less a codification of the divergence of existing practice.
(In other words, if you've got a compiler that's rejecting the code, and even if it has a backwards-compatibility mode, I'd be surprised if the backwards-compatibility mode turned stdin into a compile-time constant.)
All supported (and even older) versions of Visual Studio are perfectly capable of compiling C89 code. Also C99 is backward compatible with previous revisions of the language, so a C99 compiler should be able to compile just fine C89 code.
Although you might get some warnings, the code should compile and work just fine if the code is portable of course.
I just read: C Wikipedia entry. As far as I know there are 3 different versions of C that are widely used: C89, C99 and C11. My question concerns the compatibility of source code of different versions.
Suppose I am going to write a program (in C11 since it is the latest version) and import a library written in C89. Are these two versions going to work together properly when compiling all files according to the C11 specification?
Question 1:
Are the newer versions of C i.e. C99, C11 supersets of older C versions? By superset I mean, that old code will compile without errors and the same meaning when compiled according to newer C specifications.
I just read, that the // has different meanings in C89 and C99. Apart from this feature, are C99 and C11 supersets of C89?
If the answer to Question 1 is no, then I got another 2 questions.
How to 'port' old code to the new versions? Is there a document which explains this procedure?
Is it better to use C89 or C99 or C11?
Thanks for your help in advance.
EDIT: changed ISO C to C89.
Are the newer versions of C i.e. C99, C11 supersets of older C versions?
There are many differences, big and subtle both. Most changes were adding of new features and libraries. C99 and C11 are not supersets of C90, although there was a great deal of effort made to ensure backwards-compatibility. C11 is however mostly a superset of C99.
Still older code could break when porting from C90, in case the code was written poorly. Particularly various forms of "implicit int" and implicit function declarations were banned from the language with C99. C11 banned the gets function.
A complete list of changes can be found in the C11 draft page 13 of the pdf, where "the third edition" refers to C11 and "the second edition" refers to C99.
How to 'port' old code to the new versions? Is there a document which explains this procedure?
I'm not aware about any such document. If you have good code, porting is easy. If you have rotten code, porting will be painful. As for the actual porting procedure, it will be easy if you know the basics of C99 and C11, so the best bet is to find a reliable source of learning which addresses C99/C11.
Porting from C99 to C11 should be effortless.
Is it better to use C89 or C99 or C11?
It is best to use C11 as that is the current standard. C99 and C11 both contained various "language bug fixes" and introduced new, useful features.
In most ways, the later versions are supersets of earlier versions. While C89 code which tries to use restrict as an identifier will be broken by C99's addition of a reserved word with the same spelling, and while there are some situations in which code which is contrived to exploit some corner cases with a parser will be treated differently in the two languages, most of those are unlikely to be important.
A more important issue, however, has to do with memory aliasing. C89 include
rules which restrict the types of pointers that can be used to access certain
objects. Since the rules would have made functions like malloc() useless if
they applied, as written, to the objects created thereby, most programmers and
compiler writers alike treated the rules as applying only in limited cases (I doubt C89 would have been widely accepted if people didn't believe the rules applied only narrowly). C99 claimed to "clarify" the rules, but its new rules are much more expansive in effect than contemporaneous interpretations of the old ones, breaking a lot of code that would have had defined behavior under those common interpretations of C89, and even some code which would have been unambiguously defined under C89 has no practical C99 equivalent.
In C89, for example, memcpy could be used to copy the bit pattern associated with an object of any type to an object of any other type with the same size, in any cases where that bit pattern would represent a valid value in the destination type. C99 added language which allows compilers to behave in arbitrary fashion if memcpy is used to copy an object of some type T to storage with no declared type (e.g. storage returned from malloc), and that storage is then read as object of a type that isn't alias-compatible with T--even if the bit pattern of the original object would have a valid meaning in the new type. Further, the rules that apply to memcpy also apply in cases where an object is copied as an array of character type--without clarifying exactly what that means--so it's not clear exactly what code would need to do to achieve behavior matching the C89 memcpy.
On many compilers such issues can be resolved by adding a -fno-strict-aliasing option to the command line. Note that specifying C89 mode may not be sufficient, since compilers writers often use the same memory semantics regardless of which standard they're supposed to be implementing.
The newer versions of C are definitely not strict super-sets of the older versions.
Generally speaking, this sort of problem only arises when upgrading the compiler or switching compiler vendors. You must plan for a lot of minor touches of the code to deal with this event. A lot of the time, the new compiler will catch issues that were left undiagnosed by the old compiler, in addition to minor incompatibilities that may have occurred by enforcing the newer C standard.
If it is possible to determine, the best standard to use is the one that the compiler supports the best.
The C11 wikipedia article has a lengthy description of how it differs from C99.
In general, newer versions of the standard are backward compatible.
If not, you can compile different .c files to different .o files, using different standards, and link them together. That does work.
Generally you should use the newest standard available for new code and, if it's easy, fix code that the new standard does break instead of using the hacky solution above.
EDIT: Unless you're dealing with potentially undefined behavior.
When trying to compile some C code in Visual Studio, I often get numerous errors. The reason for this problem is Visual Studio's C compiler only supports an old version of C. How can I quickly fix all of my C code to be compatible with the Visual Studio compiler?
For example, I'm trying to compile websocket.c and associated headers—from http://libwebsockets.org/trac/libwebsockets. I'm getting a lot of errors about "illegal use of this type as an expression" which, according to other answers, indicates that I need to move my variable declarations to the beginning of every block.
The problem with compiling C in Visual Studio
Visual Studio does not provide full support for ANSI C. If you want C code to be portable enough to compile with Visual Studio, you'll probably have to target C89 or have it compile as C++ code. The first option is unnecessarily restrictive, unless for some reason you really really love the '89 standard C and you hate all of the new features of later standards.
Compiling as C++
The second option, compiling as C++, can be achieved, as dialer mentions in his comment, by changing the target language type. You can do this by right-clicking the source file(s), and selecting Properties, navigate to C/C++ -> Advanced and changing the Compile As option to Compile as C++ code.
You can also specify the source file type as C++ by using the /Tp <filename> switch on the command line, or use the /TP switch to compile everything as C++.
Problems with Linking
If you're linking to a library written in C, the above fix can cause linking to fail. This is because, now that you're compiling your C files as C++, the function names will be mangled. When the compiler adds the library and tries to match the name of the function you called to one exported by the library, it will fail because the name exported by the library will not be mangled.
To combat this problem, C++ allows you to specify that specific names are exported with "C" linkage, which tells the compiler that the names are not mangled. This is usually done by prefixing the function declaration with extern "C", or placing everything in a block of
extern "C" {
/* header contents here */
}
Well-disciplined C library developers know about this problem and will use techniques, such as macros, to combat it. A common technique is to detect when the user is compiling as C++, and place macros similar to these at the beginning and end of a block of declarations in a header file:
#if defined (__cplusplus)
#define BEGIN_EXTERN_C extern "C" {
#define END_EXTERN_C }
#else
#define BEGIN_EXTERN_C
#define END_EXTERN_C
#endif
If you're using well-established and well-coded C libraries, the headers probably contain something similar to this. If not, you might need to do it yourself (and if the library is open-source, submit the changes as a patch!)
The future of C in Visual Studio
There is an MSDN blog post from July 2013, which announced that a large number of C99 features have been implemented for Visual Studio 2013. Part of the reason for this seems to be that the features are mentioned in parts of some C++ standards, so they would be required anyway. The new features include new math.h functions, new inttypes.h types and more. See the post for a full list.
An earlier post gives the following tidbits:
Additionally, some C99 Core Language features will be implemented in 2013 RTM:
C99 _Bool
C99 compound literals
C99 designated initializers
C99 variable declarations
Note that there are features missing, including:
The tgmath.h header is missing. C compiler support is needed for this header.
Note that the ctgmath header was added—this is possible because that header does not require the tgmath.h header—only the ccomplex and
cmath headers.
The uchar.h header is missing. This is from the C Unicode TR.
Several format specifiers in the printf family are not yet supported.
The snprintf and snwprintf functions are missing from stdio.h and wchar.h.
Although you can expect them in the future:
We don't hate snprintf() (quite the contrary), we just missed it and ran out of time.
Note that other language features that don't have to do with the standard library are still not available.
It looks like standard C will receive more support in the future, although probably just because the implementation of more modern features is necessary to support C++11 and C++14.
<tgmath.h> and its associated compiler magic are special and I don't know our plans for them (as Pat's post explained, C++ has overloading/templates and doesn't need C compiler magic).
I am trying to compile a console C application on HP-UX machine using the aCC compiler [HP C/aC++ B3910B A.06.26].The compilation always failing with the below error :
******"Common/Common.c", line 153: error #2020: identifier "snprintf" is undefined
snprintf( BufferMessage, MSG_SIZE,
^
1 error detected in the compilation of "Common/Common.c".
gmake: *****[Common/Common.o] Error 2********
However the Common.C file include already the library which contain normally the method snprintf.
any idea to solve this isse plz?
Thanks in advance for all
snprintf() was introduced in C99, and is defined in <stdio.h>, so your compiler must support that version of the C standard. If it does not support C99 then use sprintf() instead.
Version 6 of the HPUX C compiler is C99-compliant but you may need switches to enable it.
The 6.20 release notes stated that the next release should switch the default mode from C89 to C90, and you're running 6.26. It appears that it did happen in 6.25, which was the release following 6.20.
You could force C99 mode by using cc -AC99 (or cc -Ae now that C99 is the default) to see if that helps. It may be that, even though the default C compilation mode is C99, you still have to specify it's C rather than C++.
Some other things to check:
See if you've included the stdio.h header.
See if you get a similar problem with just printf, which is also in that header.
Run the compiler generating pre-processor output (cc -E) and check that it's defined somewhere.
I read with interest the post "How universally is C99 supported ?". One of the comments therein points that Microsoft doesn't support C99. But the comment symbol // works with VS 2008 and this symbol is in C99. I have two questions:
To what extent VS 2008 support C99?
Is it ok in the same code to mix C89 and C99 syntax together? So if I write my code in C89 and then place a comment //. This means that I have mixed-coding. So what does the compiler do in such a case? Check my code first with c89 and then with C99 to accept that I use // for commenting?
MSVC supports very little of C99 in C mode. The few things that it does (like '//' comments) are really extensions they've added to C90 mode that come from C++, which may happen to also be in C99. When compiling C code, MSVC treats '//' comments as an extension to C90, not that you're intermixing C90 code with C99 code.
You'll get 'better' C99 support by compiling your C files as C++ - in that way you'll get declarations that can be interspersed with statements and variable declarations in for statements that are scoped to the for loop, for example.
Microsoft seems to have zero interest in adding C99 support to MSVC - even as they add things from C99 to the C++ compiler mode (like stdint.h being added in VS2010) since some additional C99 things are being added to C++ in C++0x.