trying to use '#include <stdbool.h>' in VS 2010 - c

I'm trying to use the stdbool.h library file in a C program. When I try to compile, however, an error message appears saying intellisense cannot open source file stdbool.h.
Can anyone please advise how I would get visual studio to recognise this? Is this header file even valid? I'm reading a book on learning C programming.

typedef int bool;
#define false 0
#define true 1
works just fine. The Windows headers do the same thing. There's absolutely no reason to fret about the "wasted" memory expended by storing a two-bit value in an int.
As Alexandre mentioned in a comment, Microsoft's C compiler (bundled with Visual Studio) doesn't support C99 and likely isn't going to. It's unfortunate, because stdbool.h and many other far more useful features are supported in C99, but not in Visual Studio. It's stuck in the past, supporting only the older standard known as C89. I'm surprised you haven't run into a problem trying to define variables somewhere other than the beginning of a block. That bites me every time I write C code in VS.
One possible workaround is to configure Visual Studio to compile the code as C++. Then almost everything you read in the C99 book will work without the compiler choking. In C++, the type bool is built in (although it is a 1-byte type in C++ mode, rather than a 4-byte type like in C mode). To make this change, you can edit your project's compilation settings within the IDE, or you can simply rename the file to have a cpp extension (rather than c). VS will automatically set the compilation mode accordingly.
Modern versions of Visual Studio (2013 and later) offer improved support for C99, but it is still not complete. Honestly, the better solution if you're trying to learn C (and therefore C99 nowadays) is to just pick up a different compiler. MinGW is a good option if you're running on Windows. Lots of people like the Code::Blocks IDE

Create your own file to replace stdbool.h that looks like this:
#pragma once
#define false 0
#define true 1
#define bool int
In Visual Studio 2010 I had an issue using typedef int bool; as suggested elsewhere. IntelliSense complained about an "invalid combination of type specifiers." It seems that the name "bool" is still special, even though it's not defined.

Just as a warning, on x64 platforms, VS2017 (I'm not sure about previous versions) defines bool as a value of 1 byte on C++ (e.g. a char). So this
typedef int bool;
could be really dangerous if you use it as an int (4 bytes) in C files and as a native bool in C++ (1 byte) (e.g. a struct in a .h might have different sizes depending if you compile it with C or C++).

Related

Is it possible to compile C89 code on MS Windows?

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.

Why doesn't C code compile properly in Visual Studio?

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).

How to port uint32_t in C to Windows 7 (32-bit)

Recently I have come across a program which contained data types like
uint32_t, uint32, uint64 etc.
Can I run the program in Windows 7 (32 Bit) without making any changes?
I use Code::Blocks 10.05 with MingW.
If changes are required, which data types can replace them?
Also I would like to know which standard of C defines uint32_t, uint32 etc?
Is it the so called gcc C?
These are from <stdint.h>, a C standard header introduced with C99, I think.
If you don't have C99 or a compatible header already in your system, which you really should have and really should investigate, you need to re-create the definitions yourself.
To do this you need to introduce a bunch of typedefs:
typedef unsigned int uint32_t;
and so on, of course after verifying that unsigned int is indeed exactly 32 bits on your compiler.
But this shouldn't be necessary, I think even Visual Studio has enough C99 support now to provide this header.

Is there any good reason not to use 'define' with variable argument length?

Recently I came upon this code:
#define LOG(type, str) printf(str)
#define LOG1(type, str,arg1) printf(str,arg1)
#define LOG2(type, str,arg1,arg2) printf(str,arg1,arg2)
#define LOG3(type, str,arg1,arg2,arg3) printf(str,arg1,arg2,arg3)
#define LOG4(type, str,arg1,arg2,arg3,arg4) printf(str,arg1,arg2,arg3,arg4)
The code was written recently. So I guess it can be compiled with C99.
My question is: Why not use a simple macro with variable arguments length? We would just limit ourselves to LOG macro and nothing more. Not to mention that we won't have to add LOG5, LOG6, etc. Would something terrible happen if we get a stack trace, run out of memory, anything that would make this solution useful?
I am a minimalist, if we can get fewer lines the better. But am I missing something here? Was this intentional or it is a bad coding practice?
Preprocessor support for variadic macros looks to me the only good reason. We had for decades in our project LOG, LOG1 etc, but did upgrade to ... recently.
As per wikipedia:
Several compilers support variable-argument macros when compiling C and C++ code: the GNU Compiler Collection 3.0,[2] Visual Studio 2005,[3] C++Builder 2006, and Oracle Solaris Studio (formerly Sun Studio) Forte Developer 6 update 2 (C++ version 5.3).[5] GCC also supports such macros when compiling Objective-C.
If you know your platform, then use fancy variadic macros. If there are few to support, then things could turn out to be more interesting

Visual C++ 2010 Express C2099 Error for structures initialized with constants in a macro

Compiler: Microsoft Visual C++ 2010 Express, SP1
Project Property: C/C++ Advance Compile As: Compile as C Code (/TC)
Message:
error C2099: initializer is not a constant
Simple Test Case Showing Error:
typedef struct
{
char *stringP;
int lino;
} foo_t;
#define bad {static foo_t foo ={__FILE__,__LINE__};}
#define good {static foo_t foo ={"filename",10};}
int main()
{
bad; // error C2099: initializer is not a constant
good; // no error
return 0;
}
This generates a C2099 error. This code compiles & links correctly under gcc but not Visual C++ 2010 Express (compile as C Code - i.e. /TC option).
Your code compiles well on my system (MS Visual Studio 2005).
You can preprocess your code to try finding the problem manually:
cl your_file.c /E > stuff.c
This generates a preprocessed file (you probably have to supply a whole lot more command-line options; you can copy-paste them from the project's Property Pages).
cl stuff.c
This should reproduce the problem. Then try looking at the code in stuff.c; if you don't see the problem immediately, try tweaking it (e.g. replacing complex things with 0) - this should hint on the problem.
(Since your system is much newer than mine, some details may be different, e.g. maybe the compiler on your system is called something other than cl, but the idea will probably work)
For some reason the Microsoft C compiler does not recognize the __LINE__ preprocessor macro as a constant (presumably because it changes from line to line?), so you can't use it to initialize a structure member.
Generating the preprocessed .i file doesn't really help because it generates legal code that compiles just fine after __LINE__ has been replaced with a constant. Apparently, the C compiler is not trying to compile this same preprocessed output.
You should be able to use
foo.lino = __LINE__;
later without any problems. This seems to be a gripe from the Microsoft C compiler. Other C compilers I've used don't seem to have any problems with this use of __LINE__.
The only workaround I've been able to find is to compile the file as C++ code (/Tp).
__LINE__ macro is not recognized as constant by MSVC compiler when "Edit & Continue" debug database mode is enabled. If you don't care about "Edit & Continue", you can switch to another database mode and the problem should disappear.

Resources