Include precompiled header in ifdef - c++

I have a cross-platform project and thing is on Windows I want to use precompiled headers(its really vital in this case) and Linux I dont want it. So I would like to have something like this:
#ifdef _WIN32
#include "precompiled.h"
#endif //#ifdef WIN32
When I build on Windows I get this annoying error, claiming:
PCH warning: header stop cannot be in a macro or #if block. An intellisense pch was not generated
Is there any workaround to fix this issue?
Thanks on advance.

I already have this problem and for me one of these two options worked for me.
1) Maybe if you add #pragma once at the start of the file (even before the #ifndef _WIN32 header guard).
2) Or you can add on your header files this skecth:
#ifndef MYHEADER_H
#define MYHEADER_H
... contents of myheader.h
#endif /* MYHEADER_H */
This will guarantee your header will be compiled just once and this warning will disapear (at least for me).
Hope it works!

Related

Unexpected #else

For some reason I can't explain, the compiler is outputting an error saying that it found an unexpected #else token.
This occurs at the beginning of the file :
#if defined( _USING_MFC )
#include "stdafx.h"
#else
#include <windows.h>
#endif
There is nothing before that peice of code expect several (single-line) comments.
This error occurs in a .cpp file. What you see above is the beginning of the file. There is nothing before that.
I tried adding the following code before the code defined above, and the error is now an unexpected #endif
#if 1
#include "stdafx.h"
#endif
So I suspect there is an issue with the included stdafx.h file which contains the following code :
#ifndef STDAFX_H_INCLUDED
#define STDAFX_H_INCLUDED
#include <Afx.h>
#include <Windows.h>
using namespace ATL;
#endif // STDAFX_H_INCLUDED
There's really nothing special about it. I'm also including this stdafx.h file from a stdafx.cpp file that only contains the #include statement, and it compiles correctly.
Here are the project preprocessor definitions :
_DEBUG
_WIN32_WCE=$(CEVER)
UNDER_CE
WINCE
DEBUG
_WINDOWS
$(ARCHFAM)
$(_ARCHFAM_)
_UNICODE
UNICODE
_TERMINAL_FALCONX3_CE6
_NO_CPP_EXCEPTIONS
_DONT_INCLUDE_WS_HEADERS
_USING_MFC
And some extra informations :
Compiling for Windows CE 6 using Visual Studio 2008.
What would be causing this ? Thank you.
Based on the name stdafx, I assume it is a precompiled header.
A precompiler header must be the first include (preprocessor) directive in the file, you can't put anything (not even an ifdef) before it. The only exception being a few comment lines, as those would be ignore anyway.
Based on your example, you should put the #ifdef _USING_MFC into your stdafx.h, and include Afx.h there.

Remove #pragma once warnings

I am using #pragma once in my .cpps and .hpps and because of that I get a warning for each file that uses it. I have not found any option to disable this kind of warning, only the thing of #ifndef MY_FILE_H #define MY_FILE_H /*...*/ #endif.
So would you recommend me to replace each #pragma once with ifndefs?
in header:
#define MYFILE_H
// all the header
and in the other files:
#ifndef MYFILE_H
#include "myfile.hpp"
#endif
// the rest of the file
What do you think, is it better to use it like this? Or there is an option to disable the #pragma once warnings in GCC, that I do not know?
The common approach is to place the guard in the .h file only:
#ifndef MYFILE_H
#define MYFILE_H
// all your myfile.hpp here
#endif
or
#pragma once
// all your myfile.hpp here
The rest of files (other .cpp) should do nothing regarding the guards. You should not get warnings by doing this.
Indeed the #ifndef guard can always be used, but just to remove the warning while compiling the source which uses #pragma once I would recommend to use the -woption while compiling.
e.g. gcc -w -o <output file> <input file(s)>

How can I use the #error directive to provide the user pointers to useful information?

Suppose I have a file like the following
Mainfile.cpp
#include "stdafx.h"
#include <stdlib.h>
#include "Myfile.h"
#ifdef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
int _tmain(int argc, _TCHAR* argv[])
{
system("pause");
return 0;
}
Myfile.h
#pragma once
#undef _MYFILE
#define MYFILE
My goal is to provide additional information ("Please refer to ....") in case something is missing (MyFile.h was not included/found on the path).
How can I handle this with a third party library, like Boost? In this case, I don't have control on Boost and I cannot handle the definition of _MYFILE: then how can throw the error?
Pseudo code
#include "boost/boost.h"
#if (boost is not included || directory path is not set || boost .h file not found)
#error: Set boost path and compile again
#endif
It is impossible to do what you want in C/C++ code. Once you enter #include "myfile.h" it is up to compiler to locate that file and throw an error if it's nowhere to be found.
You are also misusing #ifndef ... #error ... #endif.
Some people use it to track header dependencies; imagine you have a header messages.h which requires header mytypes.h. Usually you just write something like this:
// File mytypes.h
#ifndef MYTYPES_H
#define MYTYPES_H
typedef unsigned char UINT8;
// ...
#endif
// File messages.h
#ifndef MESSAGES_H
#define MESSAGES_H
#include "mytypes.h"
// ...
#endif
But you can also write messages.h like that:
#ifndef MESSAGES_H
#define MESSAGES_H
#ifndef MYTYPES_H
#error I need mytypes.h to compile!
#endif
#endif
but it quickly becomes a chore to insert #errors for all the headers you depend on and then include those dependencies over and over again in all the source files where your header is needed. So in most cases first approach is the way to go.
You also need to decide what type of include guard you want to use. Don't #define MYFILE if you're already using #pragma once. Choose one and stick to it. (and remember that #pragma once is nonstandard).
Finally last but not least: if you really need to be that user friendly you will need to use your build system to verify that all extra libraries are installed and their headers are available. My guess is you're using Visual Studio's native builder. I don't know that one but I read it has pre-build actions so perhaps it's possible to define one which verifies boost location via some native visual studio calls or simply by running a batch file included in the project.
Shouldn't
#if _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
be
#ifndef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif

What is the reason for #pragma once inside header guards?

Just seen this inside <boost/asio.hpp>
#ifndef BOOST_ASIO_HPP
#define BOOST_ASIO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
/// ....
#endif // BOOST_ASIO_HPP
Disregarding the _MSC_VER preprocessor checks, what is the benefit of having the #pragma once in this case? Doesn't the preprocessor header guard ensure in all cases and on all platforms, the header contents are only ever included once?
#pragma once specifies that the file will be included (opened) only once by the compiler when compiling a source code file. This can reduce build times as the compiler will not open and read the file after the first #include of the module.
If you don't #pragma once, the file will be opened each time it is needed and compiler will stop parsing it on #ifndef BOOST_ASIO_HPP, if it has been defined.
Specifies that the file will be included (opened) only once by the compiler in a build. This can reduce build times as the compiler will not open and read the file after the first #include of the module
And one more related question from SO
Yes header guards ensures that the header contents are included only once. but here you are using #pragma for checking another definition and not include file.
The below link is existing question on header guards in SO.
Purpose of Header guards
#pragma once has the same purpose, but include guards are intended to require a deeper analysis to ensure a file is included exactly once - e.g.
// somerandomfileinmyproject.cpp
#undef BOOST_ASIO_HPP
#include <bost/asio.cpp>
Unless the compiler does handle such cases correctly, it still needs to open the file and pass it through the preprocessor even though it has been included before.
You can reproduce the effect of the #pragma once in a standard way using the following:
#if !defined GUARD_SYMBOL
#include "GUARDED_FILE"
#endif
although it is much more verbose. As others have said, it helps with compilation times since the file is not searched for / opened instead of opening the file and ignoring everything inside it - the file still has to be parsed by the preprocessor.

include of header with ifdef

I've tried placing the following in my C++ code:
#ifdef _WIN32
#include "stdafx.h"
#endif
but I getan error:
PCH warning: header stop cannot be in a macro of #if block. An IntelliSense PCH file was not generated.
I'm trying to let my code work both on windows and linux, stdafx.h does not work on linux where it's a must on visual studio.
Is there another way to use the include with ifdef?
Unfortunately you can not do that with precompiled header and using Microsoft MSVC. The MSVC totally ignores all code (and whatever garbage) lines that precede that #include "stdafx.h" line. As result the #endif will be unexpected to it.
Put that #ifdef _WIN32 and what not inside of stdafx.h.
I have just created an empty stdafx.h. With follow content for solutions without pre-compiled headers
#pragma once
//this is only for using Common modules with Precompiled headers. We can't disable it using a preprocessor(
//https://stackoverflow.com/a/36271896/6160632