with MVS2008, this line works fine:
_fsopen(file_name, "wb+", _SH_DENYRW);
Borland C++builderX from 2003 complains about the argument _SH_DENYRW. I changed to
_fsopen(file_name, "wb+", SH_DENYRW);
removing the underscore and Borland compiles well now. Is it good what I'm doing? I saw this modification somewhere on the web.
Thanks a lot..
Microsoft has been working bit by bit over time to make the names used in their C/C++ headers and libraries more standards compliant (though they aren't necessarily doing the same for names in the SDK headers and libraries - a subtle but important distinction). So you'll find that more and more of names that aren't in the standard are being prefixed with an underscore.
But MS often provides the ability to use the old, non-standards compliant names for backwards compatibility. You should be able to use the SH_DENYRW name in either MSVC or Borland unless you're telling the compiler to use strict standards compliance (for example, with the /Za option), since MSVC defines the following in share.h:
#if !__STDC__
/* Non-ANSI names for compatibility */
#define SH_DENYRW _SH_DENYRW
#define SH_DENYWR _SH_DENYWR
#define SH_DENYRD _SH_DENYRD
#define SH_DENYNO _SH_DENYNO
#endif
#endif /* _INC_SHARE */
Related
I got this book "Beginning C" by Ivor Horton and I'm half way through it and I like it; so far so good. I use Code::Blocks on Windows as my IDE, and now I've run into the problem I cannot solve for about 3 days now.
The author mentions some "optional" functions in <string.h>, like strnlen_s(), and also says that these are available in the new standard — C11 (the book is from 2013; I don't know how new C11 actually is), and he also gives a piece of code that will determine "whether the standard library that comes with your C compiler supports these optional functions".
This is the code:
#include <stdio.h>
int main(void)
{
#if defined __STDC_LIB_EXT1__
printf("Optional functions are defined.\n");
#else
printf("Optional functions are not defined.\n");
#endif
return 0;
}
So I run the code to check if GCC in Code::Blocks does and determine that it doesn't. The book didn't recommend the compiler nor the IDE; I picked up Code::Blocks with GCC on my own, since that's what I do my exams in at college, so I figured I should get familiar with the environment.
The thing is, I have no idea how to "fix" this, since strnlen() doesn't work, strnlen_s() doesn't work, and bunch of others, and I can't really continue through a book. Not that I need them, or that I can't do it any other way (strlen() works just fine) but it would be nice to know how to use non-standard functions.
Up to date versions of GCC certainly do support C11, you need to enable it with the compiler flag -std=c11.
I presume you're using some flavour of MinGW with Code::Blocks - I recommend using MinGW-W64 as it is actively maintained and very up to date.
Also, bundled toolchains of MinGW-W64's gcc are available at TDM-GCC.
The Code::Blocks IDE itself doesn't care which version of C you're using, that doesn't affect what libraries you have available.
You are speaking of the optional Annex K Microsoft pushed through.
K.2 Scope
1 This annex specifies a series of optional extensions that can be useful in the mitigation of
security vulnerabilities in programs, and comprise new functions, macros, and types
declared or defined in existing standard headers.
2 An implementation that defines __STDC_LIB_EXT1__ shall conform to the
specifications in this annex.380)
3 Subclause K.3 should be read as if it were merged into the parallel structure of named
subclauses of clause 7.
It is generally seen as deeply flawed, and Microsoft trying to force it's use as a severe nuisance.
That's especially the case as they are the only major player implementing them, and their versions are non-conformant.
glibc with gcc for example provide most supposed advantages of that annex without introducing new functions, discouraging use of half the standard-library and forcing such a cumbersome API on programmers.
You might want to read the C tag-wiki, and especially grab a draft of the C11 standard (which is from 2011, as the name should imply).
The optional Annex K from the C11 Standard is not widely adopted yet (see Deduplicator's comment below). For instance as of February 2015 it hasn't been merged into glibc.
The good news is that you might try an alternative compiler. For instance Pelles C for Windows is a modified LCC with enhanced support for newest C11 features (like atomics and C11 threads model, that I believe are also mentioned in your book). Here is some basic program, that compiles and runs in it:
#include <stdio.h>
#include <string.h>
int main(void)
{
#if defined __STDC_LIB_EXT1__
printf("Optional functions are defined.\n");
#else
printf("Optional functions are not defined.\n");
#endif
char *str = "Hello Annex K";
printf("%zu\n", strnlen_s(str, 5));
return 0;
}
Output is:
Optional functions are defined.
5
Press any key to continue...
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).
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
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++).
I'm wondering how widely are __func__ (part of C99, but I'm compiling as C89) and __FUNCTION__ supported.
I have an old code base that is mostly using manual const char* id; variables that are then passed to various (mostly logging) functions. I would like to get rid of this and move the function name into a macro.
The predefined identifier __func__ was added to the 1999 ISO C standard; the older 1990 C standard doesn't have it.
Support for __func__ in pre-C99 compilers will depend on which compiler you're using.
Modern versions of gcc support __func__ even in C90 mode (-ansi or -std=c89).
Before __func__ was added to the standard, gcc implemented its own equivalent extension, but with the name __FUNCTION__. (gcc also supports __PRETTY_FUNCTION__, which is identical to __func__ and __FUNCTION__ for C, but provides more information in C++.)
The gcc manual gives some advice:
__FUNCTION__ is another name for __func__. Older versions of GCC recognize only this name. However, it is not standardized. For maximum
portability, we recommend you use __func__, but provide a fallback
definition with the preprocessor:
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
which implies that gcc added support for __FUNCTION__ in version 2. gcc 2.0 was released in 1992; you're very unlikely to be using a version of gcc that doesn't support at least __FUNCTION__, if not __func__.
Note that since __func__ and __FUNCTION__ are predefined identifiers, not macros, you only need the #define once, not in each function. On the other hand, you can't use #ifdef __func__ or #ifdef __FUNCTION__ to detect the level of support.
As for other compilers, a quick experiment indicates that Microsoft Visual C++ 2010 Express supports __FUNCTION__, but not __func__ or __PRETTY_FUNCTION__, when compiling C code. The above block of code from the gcc manual compiles under MSVC, but it results in __func__ being defined as "<unknown>". It shouldn't be too difficult to adjust it to recognize that MSVC supports __FUNCTION__. (I don't know whether older versions do so.) You can probably use the predefined macro _MSC_VER for this. Microsoft's documentation says that support for __FUNCTION__ goes back at least to the 2003 release, which sets _MSC_VER to 1300, so changing the second line to
# if __GNUC >= 2 || _MSC_VER >= 1300
is a good start. (It may well have been supported in earlier releases.)
For compilers other than gcc and MSVC, you'll have to consult their respective documentation -- but in any case, the block of code recommended in the gcc manual should work for any compiler, at worst falling back to "<unknown>".
The boost current_function.hpp header contains several #defines for the ways to get the current function on different platforms.
That's not to say that those platforms don't support other ways of getting the current function, but the choices made for boost are likely to represent nice (if not the nicest) ways of getting the information on those platforms.
An adaptation of this header for your code (and for C) could well be what you need.
I believe it is regardless what C standard is used (if C89 or C99). The more important factor is the compiler being used since it is the one that will implement __func__. The latest GCC compilers will add __func__ no matter the standard being used. I think. :)