(Hidden?) MS Visual Studio settings affecting C/C++ compilation - c++

I have a C++ file that compiles fine in one project, but not in another. The file is the exact same C++ file in both projects.
Both projects are MFC dialog-based projects. They have slightly different stdafx.h files... but if I'm prepared to break the rest of the project, I can make them identical... and still get this compiler error. Equally, they have considerably different include paths, but if I break even more of the project and make the include paths identical, I still get the error. It goes without saying that I have made all my preprocessor directives identical... and I still get the error.
So, as far as I can tell, I'm down to compiler switches. I've made them identical (within reason - I haven't bothered to change the /Fp, /Fd or /Fo output files), but still it refuses to compile. Are there any "hidden" settings or anything else that might be affecting compilation?
[Note: the following is included mostly for historical reasons - it led to an unintentional over-emphasis when this question was originally posed, and so led to predictable comments and answers which didn't help resolve the intended "when is identical not identical?" question]
The error itself is error 2894 (templates cannot have 'C' linkage). I understand this error, but not how/why it is occurring. It occurs within a bunch of C header files pertaining to a C library. They are all neatly wrapped in extern "C" {...} declarations, with #ifdef __cplusplus correctly applied. But extern C {...} is not something I'm very familiar with, so... is there anything special about extern "C" {...} that might be a factor?

If a single C++ file is compiled under the same conditions, it leads to the same result. It doesn't matter if it is in a project with zero other files, or a hundred other files - the compiler compiles each file individually.
Therefore, if a single C++ file compiles with different results, then that is either because:
It is not really the same single C++ file, or
It is not really the same compilation conditions.
You can see exactly what the Microsoft Visual C++ compiler thinks your "single" C++ file truly is by specifying /showIncludes as an "advanced" compiler option. You might be surprised to see how different your "identical" C++ file is (and this was the case here).
Equally, you can see the explicit C++ compiler conditions listed under the Command Line summary that appears at the bottom of the list of C/C++ options in the project properties in Visual Studio.

wspapi.h includes some C++ template code outside of its internal extern "C" section. If you were to externally wrap the header in an extern "C" declaration, you would break it.
For example, you cannot do this:
extern "C"
{
#include <wspapi.h>
}
Similarly, if a preceding header or code has failed to terminate an extern "C" block so that all the content of the header is given C linkage, the same situation arises.
Put simply, wpsapi.h has been included within a C linkage block, it has nothing to do with "hidden options".

Related

g++ - Finding appopriate Windows libraries to link so as to compile FANN library

For various reasons I have been trying to compile the FANN library myself. I'm on Windows 10 with MinGW. To keep things simple I was going for something like this to start with:
g++ mushroom.c -o shroom.exe -lm -I src\ -I src\include\ src\doublefann.c
(mushroom.c includes <stdio.h> and "fann.h".)
Using the -I src\ -I src\include\ src\doublefann.c allowed me to get rid of various undefined reference errors resulting from header files not being found, but it now keeps throwing the following undefined reference:
doublefann.c:(.text+0x4ee9): undefined reference to GetTickCount()
FYI, this appears in fann.h (line 54):
/* COMPAT_TIME REPLACEMENT */
#ifndef _WIN32
#include <sys/time.h>
#else /* _WIN32 */
#if !defined(_MSC_EXTENSIONS) && !defined(_INC_WINDOWS)
extern unsigned long __stdcall GetTickCount(void);
In short, this seems to be an error with linking windows libraries, and I don't really know how to proceed so as to find the relevant ones to link.
Here is the full fann.h and the full doublefann.c
DISCLAIMERS AND NOTES
EDIT: Since going to bed last night, I refined my approach so you don't have to edit the actual FANN source files. (For the record, my original approach worked and you can look at the edit history to see what that was if you really care).
Firstly, for anyone else stumbling across this question, I should note that it's not really necessary to use FANN this way. The website provides cmake files as well as Visual Studio Solutions that both work fine.
WHATS WRONG
Looking back at the question, the problem is obvious and I hate myself for not seeing it before the first of way too many hours. You'll notice that all of the files in that command have the *.c extension. Forgive me for treating you like a novice, but I can't assume you know anything or I risk giving a bad answer. *.c is the canonical file extension for C source files. The gnu toolchain is a fairly flexible piece of software, and you can compile C code with g++ without errors most of the time. But you shouldn't, because you'll get this error. Since your source file, mushroom.c, is a C source file, it'll work for you to just compile the code as C (in this case with gcc, not g++). If, however, you're using things in your program like iostream or string or classes or any other C++ code, you're right to compile it as C++ (by convention you would change the extension then to *.cpp for clarification, but I'm not sure the GNU toolchain cares). In that case, whenever you want to include C code in your C++ program, be sure to wrap it in an extern "C"{}, so that the compiler knows the calling conventions and labels are C standard, which isn't always the same as C++ standard. This means that not only does calling C code from C++ without extern "C" risk passing arguments to functions in the wrong way (good way to cause a segfault), but the way variables and functions are renamed when compiled to assembly is different between the two languages, which is why you get Undefined Reference in the linking stage, but not the compiling stage. In this case, not only is doublefann.c a C source file (which by itself links fine), but so is the library that contains the function declaration of GetTickCount(). Specifically, you're linking to %SYSTEMROOT%\System32\kernel32.dll (normally, but I believe MinGW uses PATH_TO_MinGW\lib\lib32k.a), which defines how programs can interact with the Windows Operating System at the machine-code level. The __stdcall utility is defined here to call things like GetTickCount() from the OS, which are assembly functions, within C code. Because this is in a *.dll, the compiler cannot change __stdcall to suit C++ coventions. This is due to the fact that "dll" stands for "Dynamically Linked Library". Essentially this means that these files were already compiled into machine code when Windows (or MinGW) was installed. So editing it is nonsensical, because you'd need to have intimate working knowledge of the opcodes for every x86_64 processor ever made. Thus, calling in C will do everything in a way that __stdcall expects, but calling in C++ requires the extern "C", or it'll mangle the names of your function declaration and possibly cause runtime errors.
tl;dr
FANN is written in C, C=/=C++, so don't expect a C++ compiler to always compile C code perfectly.
Solution
There are two ways to go about solving this problem.
1
If you're using C++ features/libraries, change the name of your source code to mushroom.cpp (if you want) and change the line (wherever it occurs in your program)
#include "doublefann.c"
to be wrapped like so:
extern "C"{
#include "doublefann.c"
}
If you read through fann.h, you might have noticed the lines:
#ifdef __cplusplus //line 65
extern "C"
{
#ifndef __cplusplus
} /* to fool automatic indention engines */
#endif
#endif /* __cplusplus */
Don't worry, these don't appear to conflict. Frankly, I'm not sure what these lines are meant to accomplish, but I'm sure they know what they're doing.
2
If mushroom.c really is just pure C, just compile using:
gcc -o shroom.exe mushroom.c -lm -I src\ -I src\ -I src\include\ src\doublefann.c -Wall
and that should work. I added -Wall because I love being able to make my code absolutely perfect, feel free to leave that out it just prints every warning you could have.

Building an R package with Rcpp which contains C source and header with restrict qualifier?

I have an third party source file and corresponding header (containing the declarations and include directives for GSL etc) which are written in C. I am trying to build an R package around these source files, basically making a wrappers for the functions using Rcpp. Problem is that these files contain restrict qualifier which is not part of the C++ standard, so R CMD INSTALL cannot compile the package. It does use C compiler for .c file, but want's to compile .h file with C++ compiler and it fails. it fails when it finds restrict in header file (which is included in .cpp file).
I am not that familiar with C and compiler things and Rcpp etc, so I am not sure what would be a best approach here?
Easiest thing would probably be to remove the restrict keyword. This is what I have currently done (I am suprised that R CMD INSTALL works when I remove restrict from header file but leave them to .c file). But I rather not alter the .c and .h files as they are also used in non-R environment by others (executable and in Python) and it would be nice to have identical files for all projects.
I also tried to define empty keyword restrict so that it would just "remove" restrict from function definitions if the compilation was done in C++ compiler, but I couldn't get that work. I read about similar approach somewhere but apparently it doesn't work that way.
Would it work if I could somehow tell the compiler (via Makevars or something?) that the particular .h file should be compiled with C compiler? Or is there going to be problems with C++ function calling those functions?
Or will the whole keyword even matter in terms of performance if those functions are called from R via C++ wrapper?
One thing would be to just ditch the Rcpp and use .C instead of .Call from R, but as the performance is a key here, that doesn't feel a good option, as I understand that .Call is faster (and more reliable).
Note that eventually this package could find it's way to CRAN, so the solution should be fairly portable. There seems to be some C++ compiler specific keywords for restrict but I guess those are not an option due to the portability.
It sounds like you are making a .cpp file which does #include <x.h> where x.h is a C header which uses restrict. If that's true, I think you can modify your .cpp file to do this:
#define restrict // nothing
extern "C"
{
#include <x.h>
}
Then compilation of your C++ code will not see the restrict keyword, and also I have wrapped the header in extern "C" because if the header itself doesn't do that internally, you need to, in order that your C++ compiler will not apply C++ "name mangling" to the functions declared inside.

is extern "C" required in C files ? (to solve odd Eclipse behaviour)

I am relatively new to Mixed C/C++ applications using the gcc and g++ tools.
To get the hand of it I have downloaded the iperf source code and built it with success using Eclipse.
There is one oddity: If I look into the file "Thread.c" using Eclipse it thinks there is a syntax error and underlines almost the whole file as if the code is flawed, which it is absolutely not.
This is the piece of code that triggers it:
#ifdef __cplusplus
extern "C"
{
#endif
I know what extern "C" is used for in C++ but Eclipse has problems with it when present in .c files. It happily accepts it in .cpp and .h files though.
I have checked out how the Make utility builds the iperf application and I see it always uses gcc to compile c files and g++ to compile cpp files which makes me wonder if extern "C" is actually required. It most definitely does not hurt because the gcc compiler happily deals with it but if it is not strictly required I could omit it and get better readability in Eclipse.
I have also looked at a possible solution for Eclipse's behaviour but have not really found one, if anybody can point out how to solve it that would be equally good.
If you are using Eclipse, what you seeing in editor has to do with Eclipse internal indexer/parser. Your mixed C/C++ project may compile and build with no issues, but when you open a source file which has
#ifdef __cplusplus
extern "C" {
#endif
you may see a syntax error marked on the extern "C" line. This means that "__cplusplus" symbol is defined for your C compiler in your project settings.
In order to get rid of that syntax error in the Eclipse editor, go to project Properties -> C/C++ General -> Paths and Symbols -> # Symbols tab, and select "GNU C" (or whatever C compiler you use) under "Languages" column. Scroll through Symbol/Value list on the right, find the "__cplusplus" symbol and delete it. Make sure you do that only for C compiler.
Click OK to close the project Properties window and the syntax error warning will be gone in Eclipse editor.
that piece of code is normally found in headers, and should be always be written to header files that belong to c-files. (with the corresponding closing bracket at the end of the header)
reason is, that c uses a different scheme how the functions are internally called (--> name mangeling). while the compiler can distinguish a c++ code file from c code file by its extension it can not distinguish between a c-header and a c++ header that is included from a cpp file. so it does not know if it has to mangle the name of the declared functions or not (by default it does).
then the linker tries to match the used symbols (reference to function from cpp) with the created one (defined by the c-file) it does not find the symbol if the compiler was not told not to mangle the declaration.
extern "C" is only legal in C++ and ensures that the specified function(s) have C linkage. This means that the function parameters are not mangled into the binary function name.
To ensure that the header file compiles in C we include the #ifdef __cplusplus __cplusplus is defined by a C++ compiler and not a C compiler. This use used to protect C code from the C++ only extern "C" directive.
IDE's so not use compilers for code intelligence and therefore may get things wrong.
probably just a silly workaround for your issue.
what i found is that, while using c functions in cpp file, theoretically extern is required.
But i found that in eclipse oxygen version, we do not have to specify extern c, we can directly use c functions and printf statements too in cpp file and it just works fine.
Havent tried in older versions of eclipse.
My solution may not be very helpful, but you could give it a try. It worked for me.

Strange Eclipse C++ #define behaviour

(A case of over relying on an IDE)
I have some legacy C code that I compile as C++ for the purpose of Unit testing. The C source is C++ aware in that it conditionally defines based on environment.
E.g. (PRIVATE resolves to static):
#if!defined __cplusplus
#define PRIVATE1 PRIVATE
#endif
...
PRIVATE1 const int some_var;
The problem is I just can't seem to find out what PRIVATE1 resolves to or is in C++, the compiler complains of redefinition if I add a declaration but doesn't indicate where?
I have searched my MinGW/gcc include path, the C++ ISO specification and the C++ books available to me has been to no avail.
Edit:
Sure I checked the command line and makefiles before posting.
There's nothing like this in ISO C++ spec. Most likely, PRIVATE1 (as well as PRIVATE) are defined elsewhere in the project. Note that this doesn't need to be a #define in an .h file - it can also be defined via compiler switches in the makefile. I'd suggest doing a full grep on the project directory.
If PRIVATE1 resolves to PRIVATE, and PRIVATE resolves to static, then PRIVATE1 resolves to static.
It's unlikely (but not impossible) that they are defined by MinGW itself. Macros defined by the C++ or C implementation should begin with an underscore.
Eclipse C++ managed project's are a little, well stupid!
If a project is declared C++ it still bases it's build on file extension, hence .h file preprocessed as C and not C++ header which pulls in a #define PRIVATE1 from another header file similarly wrapped by:
#ifdef __cpluplus.
The project is then linked by g++.
Your best bet is to look at the preprocessor output. You didn't post what compiler you are using, but if you check the docs, most have an option to "Preprocess to file" which will create a file with all the macros substituted. This might be able to help you figure out what is happening. In Visual Studio you use the /E option (under C/C++->Preprocessor->Generate Preprocessed File) which will turn foo.c into foo.i. This file will generally be HUGE compared to the original source file, so scroll down to the bottom to see your code.
Most likely in C++ it's defined to, well, "private:".
Can you declare a function with PRIVATE1? If so, just write a function like so:
PRIVATE1 void Foo() {
// __FUNCSIG__ in Visual Studio, not sure about GCC
std::cout << __FUNCSIG__ << std::endl;
}

what's the difference between hpp and hxx?

for gcc they should be the same, right? which one of them is more popular , i am now preparing a project from scratch and i would like to pick one among these 2.
thanks
In C++, the file extension doesn't actually matter. The use of .h, .hpp, .hxx, or no file extension are all by convention.
The standard library uses no file extension for its header files. Many projects, including Boost, use .hpp. Many projects use .h. Just pick one and be consistent in your project.
The compiler doesn't distinguish between the two extensions, so technically it doesn't matter which one you use. Personally I use the .hxx extension for header files that are only used internally in the project, and .hpp for those that should be release with the library/software.
I propose that we re-open this discussion, in view of a recent discovery that I made. For the last 9 years, I have used the following naming convention for the source files in my C and C++ projects.
C = Straight C source code, containing one or more related entry points
CPP = C++ source code, containing one or more related entry points
H = Declaration of functions, macros, structures, typedefs, etc.
INL = Inline (function bodies) that are the bodies of two or more functions whose main definition file is a C or CPP file, into which they are incorporated by #include
An example of these common function bodies, MyStringFunctionA, the ANSI implementation, is defined in MyStringFunctionA.cpp, while MyStringFunctionW, the Unicode (wide character) implementation, is defined in MyStringFunctionW.cpp. MyStringFunctionA.cpp and MyStringFunctionW.cpp contain the prototype, opening and closing brackets, and headers, subject to UNICODE for the wide character version. The function body is defined in the INI file, which is #included inline, within the function definition block.
Combined with generic TCHAR mappings, this approach greatly simplifies maintaining Unicode and ANSI versions, both of which remain in active use.
This naming convention worked great with Visual Studio 6. However, when I began migrating my code base to Visual Studio 2013, I discovered an annoying change that was initially confusing. Although everything compiled cleanly, when one of my INL files was open in the code editor, I would see dozens of Intellisense "errors" listed in the Errors window. I quoted the term "errors" because they are not true errors; they vanish when the INL file is closed, and the C and CPP files into which the iNL is pulled compile without errors, link, and run correctly.
Header file extensions don't usually make a difference, but I know that in some cases the extension of the .cpp file can make a difference. Depending on your compiler the front-end may choose to compile the source file as either C or C++.
This can make a difference, especially if you are combining compilation with the link phase, as it can lead to different libraries being linked (e.g. g++ vs gcc) and so you can control the outcome in your makefile.
Source code header file written in the C++ programming language; may include data types, constants, variables, and other definitions; used for declaring and storing reusable components of code.
HXX files can be inserted into a C++ program using the #include directive. For example, #include myHeader.hxx instructs the C++ compiler to include "myHeader.hxx" into the current program file.