'identifier' already has a body but identifier not found - c++

I have a Qt project using precompiled headers (not sure if that's relevant) in VS2012 and it compiles and works fine. But when I try to compile the same project in QtCreator it shows errors. First of all - both projects correspond to each other and were previously correctly configured (they compiled and worked just fine). After latest changes to the code, however, something went wrong.
Errors:
pch.h:34: error:C2084: function 'void handleExceptionByShowingMessage(std::exception &)' already has a body
main.cpp:16: error:C3861: 'handleExceptionByShowingMessage': identifier not found
These go on for 30+ lines with another function defined in pch.h (inline too) and a few more cpp files. But all errors are analogical.
From pch.h:
inline void handleExceptionByShowingMessage(std::exception &e)
{
QMessageBox msgBox;
msgBox.setText(QString::fromUtf16((ushort*)e.what()));
msgBox.setStandardButtons(QMessageBox::Discard);
msgBox.setIcon(QMessageBox::Warning);
int ret = msgBox.exec();
}
I don't paste function calls from cpp files because it's just a regular use. All cpp files include pch.h correctly (first line of code) and as I said - the exactly same code and file structure works in VS2012 (whose compiler, I believe, QtCreator actually uses...).
If you need more code/information please let me know.
Update:
Yes, all headers have #pragma once. Interesting notice though - when I moved these two function definitions to a dummy header file and included it in the pch.h, the project compiled fine.

#pragma once only prevents the file containing the directive from being included several times. You precompiled header file, pch.h, gets included when the precompiled headers are loaded, and a second time when you files are compiled. The #pragma directive sees them as separate files so it won't work in this context.
The pch.h file (or stdafx.h) is an optimization and ideally should not contain source code but only #includes to other header files. That way, including it several times won't be an issue.
Another solution would be using an include guard (#ifndef PCH #define PCH #endif), which will prevent the file to be included several times.

you may try static inline if the code is in header.
I do not know why inline does not imply static but i also stumbled about this a time ago.

Related

Why external include directory compiles multiple times?

When I am making changes to my code, the external files are compiled multiple times. I am using math library glm, and Visual Studio seem to be compiling exactly same glm/vec3.hpp file multiple times. I have included glm header multiple time, and it seems that it doesn't use previously compiled code, but recompiles it again.
For example, in my math.h I have included.
#ifndef MATH_HH
#define MATH_HH
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
...
And when I am compiling after changes to code, I see that Visual Studio compiles glm/vec3.hpp multiples times. Basically it compiles it each time that it compiles one of my edited files.
For example, the Visual Studio output looks like this:
1>C:\test\external\glm\glm\detail\type_vec3.hpp(50,1): warning C4201: nonstandard extension used: nameless struct/union
...
10>own_file.cc
11>C:\test\external\glm\glm\detail\type_vec3.hpp(50,1): warning C4201: nonstandard extension used: nameless struct/union
...
Is there a way to prevent this? Or do I need to compile them each time some cpp file uses them? Or am I just confused of Visual Studio's style warnings?
Basically it compiles it each time that it compiles one of my edited files.
That's how C++ works. It compiles source files. Including a header file is just taking the text in that file and dumping it into your source file. Therefore, if you include a header file in 3 source files, the text of that header will be compiled 3 times.
There are precompiled headers (a compiler-specific tool), and the C++20 modules feature, that can avoid this. But outside of those, there's nothing you can do.

c++ Header Files and Implementation

I m trying to understand how an IDE (I'm using Visual Studio) knows where to find the implementation for a header file's declarations.
Let's say that I have 2 cpp files and 1 header file:
main.cpp, contains main() function and includes person.h
person.h, contains some class declarations that are implemented in person.cpp
person.cpp, contains the implementation of the person.h declarations, and also defines person.h
So my understanding is that main.cpp and person.cpp know where to find the function declarations, but person.h has to search in some .cpp file for these implementations.
Now, how does Visual Studio keeps track of this? Each time a new header file is created, does VS needs to parse every .cpp file in the project to find where the declarations are implemented? Header files don't have any declaration of which .cpp files to search for, yet it finds them! Is Visual Studio scanning each .cpp file in the project?
So, what happens in a large project, with hundreds, or thousands of .cpp files? This does not appear to be very efficient, so I figure VS must do it in a different way. Do you know how?
PS: Not about compiler/linker process, but rather how VS IDE works (even before compiling or link the final exe)
Intellisense is the name of the Visual Studio feature which links definitions to declarations; which lists completions when typing identifiers; and which draws red squiggly lines under errors.
Intellisense works by continually scanning every source file in a solution, including new definitions as you type them. Records about all of the constructs in the source code are stored in a database, which is located on disk in a "solution_name.VC.db" file. When a new definition or declaration is added, whether to a header or source file, Intellisense doesn't have to take very long to look up any related items in the database.
If you delete the .VC.db file, and then open the solution, it will take a noticeably long time for Intellisense to rescan everything before it starts working very well. The IDE will also tell you that it is "parsing" files in the status bar.

Are header files not compiled (C++ Visual Studio 2015)

Just to see if it would work (I know it's awful form), I fully defined a function in a header file and made a corresponding forward declaration for said function in the main cpp file. C++ functions don't need to be defined in the translation unit they're used in, hence why header files are almost entirely just forward declarations (with the exception of inline functions). However, when I tried to compile this project, it said that there were unresolved externals.
When I moved the entire contents of the header file into a source file (removing the header file as well), it compiled just fine and executed as expected. So, are header files just not compiled when building a project, or is there just some exception I don't know about?
Additionally, even when I just go to the header file's properties in the property explorer and set its File Type to C/C++ Code and change its extension to .cpp, it still won't compile (even though it will if i just delete it and create a fresh source file, which I think is the oddest part).
(I'm working with extensions disabled /Za, if that changes anything)
Here's the code file
//main.cpp
void foo();
void main()
{
foo();
}
and the header file
//test.h
#include <iostream>
void foo()
{
std::cout << 'a';
}
Header files are included by the preprocessor into the compilation unit - cpp file. Only the source code in the cpp file is compiled by compiler after that.
When you put your function definition into the header .h file. You don't include this header file into main.cpp and compiler doesn't compile it as preprocessor doesn't include it in main.cpp.
You can review the result of preprocessor job by yourself. In Visual Studio use the /P option on the Preprocessor property page. For main.cpp output will be in main.i.
Header files are not compiled on their own, just imagine that the text is actually inside the .cpp file where it is included. This new 'merged' file is what is compiled. So you can put functions in a header file and it will be compiled when it is included in a .cpp file.
The reason it's bad is that if you include it in a second .cpp file it will try to compile again and you will have problems.
The problem with function definitions in headers is not that they're skipped. The real risk is that they're compiled twice, and that's once too many. C++ has something called a One Definition Rule, and you violate that rule by compiling a single function twice.
There's one important exception to mention: inline functions are exempt, and may be defined in each translation unit.

C++ Visual Studio DLL File

My objective is to create a dll and lib file so i'm following this guide
1) I created a new win32 Console Application project in VS, chose DLL as 'Application Type' and Emptied Project
2) I'm trying to create a database in C++. So I have 5 headers with ONLY function declarations.
3) Database.h is my top header, it looks like this:
#ifdef DBDLL_EXPORTS
#define DBDLL_API __declspec(dllexport)
#else
#define DBDLL_API __declspec(dllimport)
#endif
#ifndef __Database_H
#define __Database_H
#include "Table.h"
class DBDLL_API Database { ... };
#endif
4) Now with only headers, I tried compiling the project. It compiled but I don't see any DLLs or Libs anywhere in the project folder. How do I create them?
This is because headers are not compiled -- only CPP files are compiled (which pull in the headers -- a source file and all the headers it pulls in is called a "translation unit", which is the thing actually being compiled (independent of other TUs)).
So, in effect, the build system thinks you're building an empty project, and in this case generates nothing at all. Note that even if the headers are pulled in and compiled, unless an exported symbol is actually referenced somewhere, it may be optimized out. In such cases, you will get an (empty) DLL, but no .lib file (which can cause errors down the line if you have dependent projects looking for this .lib before there's anything in the DLL).
You'll need to create some CPP files that implement the functions declared in the headers. If you have everything in the headers and don't need any CPP files at all, then there's no point in having a DLL! (Since you could include the headers in any other project without needing any other dependency.)
Finally, your include guard (#ifndef ...) should encompass the entire header, including the DLL export macros, otherwise you'll eventually get macro redefinition warnings.
I would suggest using #pragma once instead of include guards since it's simpler and recognized by pretty much every compiler. I would also put the DLL macro goop into its own header (e.g. "dllmacros.h") and include that where it's needed (this will reduce duplication).

LLVM refuses to compile C++ source, weird errors

I've made a struct which does cached file manipulation for my application. I built and tested to in a separate project before putting it into my current one.
Ever since I've moved it over, Xcode refuses to build it. Except when I don't include the file from any Objective-C based header file.
I get one error when I try to include iostream:
And more when I comment it out:
Its file extension is .mm, however I have tried it with .cpp and .hpp, but all of them refuse to build unless I don't #include it from the Objective-C header file.
I've also tried #import from iostream and the file itself in the Objective-C header file.
Any clues as to why this is happening?
As a matter of principle, you cannot include a C++ header file from an objective-C source file.
After all, #including (or #importing) a file only means that the preprocessor replaces the #include directive by the contents of the #included file, before passing the result on to the "actual" compiler. The file extension of the header file is a matter of convention, only, it has no actual meaning.
The error messages your are seeing are clearly the result of the file being compiled as [Objective-]C rather than [Objective-]C++.
Solution: All the source files that include your C++ header file have to be either C++ (.cpp or .cc or a few other extensions) or Objective-C++ (.mm). All source files that include a header file that includes your C++ header file, also have to be C++ or Objective-C++.
EDIT: I just saw that you are defining non-inline, non-template functions in your C++ file that you want to include. This is an unrelated problem, but it will lead to "multiple definition" errors sooner or later. Those function definitions belong in a .cpp, which shouldn't get #included anywhere, only the struct/class definition belongs in a header.
Take a look here and here. You need to tell the compiler to include libstdc++. When mixing Objective-C and C++ all you're files need to have the ".mm" extension, as stated in the second link.
I suspect the error is occurring when you compile a .m or .c file that includes the same header.