Eclipse CDT graying out wrong part of code under #ifndef - eclipse-cdt

I have header base.h containing
#ifndef GUARD_H
#define GUARD_H
<my code>
#endif
Eclipse CDT is graying out everything below #ifndef GUARD_H. This would be correct if GUARD_H were defined, but it is not.
Actually, the only place where it is defined across my system is the following line, precisely as intended for an include guard.
So, I cannot see why this happens.
Moreover, among the hundreds of headers I used under Eclipse CDT in my life, and in particular under the present project, this is the first time I see such a thing.
Why does this happen?
How can I fix this?
Using
Eclipse IDE for C/C++ Developers, Version: 2018-09 (4.9.0), Build id: 20180917-1800
under Win 10.

As per this comment,
adding affected headers to Preferences -> C/C++ -> Indexer -> Index all variants of specific headers (separated by semicolon) helps.
"Index all header variants" can also help but at a possible performance cost.
I found it sometimes works.
Sometimes it doesn't, but it starts working at a later time while I am coding or navigating, without any apparent specific action on my side.
Also the opposite, sometimes code becomes greyed out, without any apparent specific action on my side.

Found this serendipitously.
Changing affected headers to something like
#ifndef GUARD_H
#define GUARD_H
<my code>
#endif // GUARD_H <-- Modification
did the job in a few cases I tried.

Related

C++ preprocessor executing both #ifdef and #ifndef

So I'm currently working on something that uses OpenCL. The OpenCL spec provides the users with a directive which must be included before the inclusion of the header (cl.h)
#define CL_TARGET_OPENCL_VERSION 110
Which basically defines the version they want to use. Suppose I'm making a library and I want my users to define this instead of me defining this inside my files. What I did was.
-----main.cpp---
#define CL_TARGET_OPENCL_VERSION 110
#include "library.h"
-------x---------
----library.h-----
#ifdef CL_TARGET_OPENCL_VERSION
#pragma message("def")
#endif
#ifndef CL_TARGET_OPENCL_VERSION
#pragma message("ndef")
#endif
.... include other headers.
--------x---------
And the compiler prints both def and ndef messages. And the OpenCL library also throws a warning that it's undefined. I thought that the library header would get substituted into main and it'd only print the def message. Is there anything I understood wrong?
I'm particularly confused as to where does the preprocessor start? If it starts from main.cpp and goes from top to down, then it surely has defined the macro. After that it sees the library inclusion, then it should only print the def message but it prints both.
This leds me to believe the preprocessor does scan the header file before including it in main? Dunno the reason why. Also I have assured that the library header isn't included elsewhere.
One interesting thing I noticed was, if i did this
-----helper.h---
#define CL_TARGET_OPENCL_VERSION 110
-------x---------
----library.h-----
#include helper.h
#ifdef CL_TARGET_OPENCL_VERSION
#pragma message("def")
#endif
#ifndef CL_TARGET_OPENCL_VERSION
#pragma message("ndef")
#endif
.... include other headers.
--------x---------
It prints the def message "twice". If anybody can explain all this I'd be grateful.
EDIT:- The files I'm compiling are main.cpp library.h and library.cpp
Library.cpp includes library.h from the start as usual. Maybe this other cpp is causing the problem?
In C/C++ programs, the compiler handles each .c and .cpp file separately.
The compilers build each source file (NOT the header files, only .c and .cpp files) independently from each other (this source files are called compilation unit).
Thus, when your main.cpp is built, the compiler finds the #define CL_TARGET_OPENCL_VERSION 110 you have added on top of the main.cpp file, emiting the defmessage.
But when the compiler builds the library.cpp file, it does not find the version define, so it emits the ndef message.
So, following this explanation, it is completely normal that in your last case, when you add the define to the .h file, the compiler emits the def message twice, once for the main.cpp file and once for the library.cpp file.
Now, the problem is where should you add the define, in order to have the program built consistently, with the same version for all the .cpp files.
Usually, all the IDEs have some configuration page where you can add global defines, for all the project, which are "inserted" into all the compilation units before everything else. So when the IDE calls the compiler, it passes the same defines to all the compilation units. You should add this kind of defines in this page.
In your IDE (I am using Code::Blocks, v 17.12), you can find this page in the menu: Project / Build Options
For each type (Debug or Release), you have to go to the tab Compiler Settings, and there to the sub tab #defines. There you can add global defines, which can be different if you are building in Debug or in Release mode (of course, if you set the same in both modes, they would be the same).
Once you have added your define here, please, remove it from the main.cpp, library.h and any other place where you may have added it, in order to avoid duplicities.
From the comments about portability:
You have several options:
Always use Code::Blocks: this would be the easiest way, since you can pass the Code::Blocks project along with the source files, and everything would be already setup.
Use cmake, which is a script build system, where you can set defines and so in the same way as using an IDE. cmake is much widely used than Code::Blocks, so maybe it is a better option.
Add a new options.h header file, where you set all the defines, and include it to all your .c/.cpp. This setup has the additional benefit that for different systems, changing only the options.h file the build can be completely different. This is a manually setup of what the IDE is doing. It has the advantage that does not rely on external tools, but the disadvantage that you have to remember to add it in all the new .cpp files added to the project.
My recommendation is go with cmake, just as the others have said.
Prefer using #ifndef XXXX_h #define XXXX_h #endif over #pragma once
If your #include search path is sufficiently complicated, the compiler may be unable to tell the difference between two headers with the same basename (e.g. a/foo.h and b/foo.h), so a #pragma once in one of them will suppress both. It may also be unable to tell that two different relative includes (e.g. #include "foo.h" and #include "../a/foo.h" refer to the same file, so #pragma once will fail to suppress a redundant include when it should have.
This also affects the compiler's ability to avoid rereading files with #ifndef guards, but that is just an optimization. With #ifndef guards, the compiler can safely read any file it isn't sure it has seen already; if it's wrong, it just has to do some extra work. As long as no two headers define the same guard macro, the code will compile as expected. And if two headers do define the same guard macro, the programmer can go in and change one of them.
#pragma once has no such safety net -- if the compiler is wrong about the identity of a header file, either way, the program will fail to compile. If you hit this bug, your only options are to stop using #pragma once, or to rename one of the headers. The names of headers are part of your API contract, so renaming is probably not an option.
(The short version of why this is problematic to use #pragma is that neither the Unix nor the Windows filesystem API offer any mechanism that guarantees to tell you whether two absolute pathnames refer to the same file.)

Bit definition error - IAR Workbench

I am a beginner with embedded programming and am using the IAR workbench for a project of mine using STM32F4Discovery. I am trying to compile an existing code and have a few errors at a few places regarding the bit definitions like the following:
Error[Pe020]: identifier "GPIO_PIN_SET" is undefined
Now, the GPIO_PIN_SET is defined in the file stm32f4xx_gpio_hal.h and is already included in my project. In order to resolve this issue when I looked up online, I have found this solution. However, I don't have the System tab in the General Options in my IAR Workbench. I have a full version of IAR Workbench and am not sure why the System tab is missing.
I also tried defining
#define ENABLE_BIT_DEFINITIONS
as stated in this link in my main.c file but to no avail.
Trying to set
#define STM32F4XX
#define USE_STDPERIPH_DRIVER
in the main.c file or defining the symbols STM32F4XX, USE_STDPERIPH_DRIVER in the Preprocessor tab in General Options as mentioned here also didn't help.
The solution could be very simple that I am probably overlooking but am not able to figure out what could I be missing. Any help would be appreciated
Including a header file in a "project" is not enough, you should actually include it (directly or indirectly) in the source file where the declarations are to be used. It would be that simple in any halfway sane development kit, but we are stuck with ST, and they force us doing it their way.
Include the "master" header in your main.c
#include "stm32f429i_discovery.h"
this would in turn include stm32f4xx_hal.h, which includes stm32f4xx_hal_conf.h, which included stm32f4xx_hal_gpio.h if the right #defines were there.
You might not have stm32f4xx_hal_conf.h
If that's the case, then copy Drivers\STM32F4xx_HAL_Driver\Inc\stm32f4xx_hal_conf_template.h into your project, rename it to stm32f4xx_hal_conf.h. Otherwise just make sure that #define HAL_GPIO_MODULE_ENABLED is not commented out.
Set the right #defines
New versions of STM32CubeF4 have been released since the tutorial you've linked was written, and a few things have apparently changed. As of version 1.6.0, define STM32F429xx in Preprocessor Options, and forget the ones above. Yes, I've noticed that there is a version 1.7.0 now, let's hope that compatibility lasts this time.

Exclude a system header file in VS2010

I'm wondering how to exclude a specified system header file in VS2010, which makes an ambiguous problem.
In my project, I use an opensource project. In which a cpp file calls
std::something::max()
where the max is a method in something.
However, max is also defined in a system header file "minwindef.h", which in my case lies at \Windows Kits\8.0\shared\minwidef.h
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
I think this is not necessary for my project.
So how do I manually prohibit this file to be included (perhaps recursively)?
You might want to #define NOMINMAX before #includeing any Windows headers.
This is such a common problem that they added this macro to remove the min and max definitions that conflict with the stl versions.
I'll try and dig up some MSDN reference for this.
Most likely, your opensource project is not designed to be "mixed" with "windows" headers.
Just don't do #include <windows.h> into the same files that include your opensource project. The limit the includes of <windows.h> to only be included in files that ABSOLUTELY need to have it, and idealy have one or more files with "windows only" functionality that are then provided to the rest of the code via it's own headers, isolating any windows functionality - that will also help if you ever decide to port your system to something other than windows.
(There are whole bunch of other macros that will sooner or late come back and bite you if you keep including Windows in your overall project)

How to have an ${include_guard_symbol} in Eclipse with an uppercase file path?

When defining code templates in Eclipse CDT, we can use a variable named ${include_guard_symbol} that translates to MYFILE_H.
I would like to have something more explicit: SRC_MYFOLDER_MYFILE_H.
I followed the steps given in an answer to Stack Overflow question Customizing include-guard for Eclipse CDT, but all I get is for ${include_guard_symbol} to return an empty string! I also saw other related questions on Stack Overflow about adding the namespace to the include guard, but that's not what I'm looking for.
I am using Eclipse version 3.5.2 with CDT version 6.0.2.
Is there another way of achieving the desired result?
The oldest version I have installed is 3.7 and I tested there and on 4.2 and the referenced link does exactly what the OP wants. (The OP is using 3.5.2). For anyone coming here in the future here are the steps
Exit Eclipse
Navigate to your workspace folder and then keep navigating to \.metadata\.plugins\org.eclipse.core.runtime\settings
I always like to make a backup of the settings folder before making mods
Load the file named org.eclipse.cdt.ui.prefs into a text editor
Add this line (I put mine at line 3)
codetemplates.includeGuardGenerationScheme=2
Save the file.
Restart eclipse
I created a folder named MyFolder under my src folder. Then I right-clicked and added a new header file the result was:
#ifndef SRC_MYFOLDER_TEST_H_
#define SRC_MYFOLDER_TEST_H_
#endif /* SRC_MYFOLDER_TEST_H_ */
Main points from this: How to customize eclipse CDT code templates
One solution is to throw out ${include_guard_symbol} in the template all together, and define it yourself, possibly using some of the other predefined variables. Something like this:
${filecomment}
#ifndef MyProject_${file_base}_h
#define MyProject_${file_base}_h
${typecomment}
${declarations}
#endif /* MyProject_${file_base}_h */
So for a header file named inc/Foo.h, the include guard would be inserted like this:
#ifndef MyProject_Foo_h
#define MyProject_Foo_h
Unfortunately, there doesn't seem to be a way to customize much beyond that. For example, if I defined a class nested in a namespace, I might want to put the namespace as part of the include guard. I can't find a way to do that in eclipse, currently.
Not really an answer to your question, but I would like to suggest an alternative. Include guards provide a working, albeit crude way to forbid code in a header file to be included more than once per compilation unit. As an alternative, you might use the
#pragma once
compiler directive. I realise that it is not defined in the standard, but it is supported by numerous compilers, including GNU, Clang, MSVC, and Intel. If you use #pragma once, you loose little portability and you avoid name clashes which I assume is the reason you want to change ${include_guard_symbol} in the first place.
You might also check out http://en.wikipedia.org/wiki/Pragma_once for a more thorough discussion.

Detecting precompiled headers

Is there a way for the preprocessor to detect if the code in current
translation unit uses(or is creating) precompiled headers?
---
The actual problem I'm facing right now is that I'm on a project that is
abusing PCH by precompiling virtually all header files. That means there is none of
the clear dependency management you can get from #includes and the compile times is awful.
Practically every change will trigger a full rebuild.
The application is way to big to just fix it in one go, and some of the old guys refuses
to belive that precompiling everyting is bad in any way. I will have to prove it first.
So I must do it step by step and make sure my changes does not affect
code that is compiled the old PCH way.
My plan is to do ifdef out the PCH.h and work on the non PCH version whenever I have some time to spare.
#ifdef USES_PCH
#include "PCH.h"
#elif
// include only whats needed
#endif
I would like to avoid defining USES_PCH at command line and manually keep it in
sync with /Y that, besides from not being very elegant, would be a pain. There is a lot of configurations
and modules to juggle with and a lot of files that don't follow project defaults.
If Visual C++ defined a constant to indicate whether precompiled headers were in use, it would probably be listed in Predefined Macros. And it's not documented there, so it probably doesn't exist. (If it does exist, it's probably undocumented and may change in a future version.)
This will not work, when using precompiled headers in Visual C++, you cannot even have any code before including a precompiled header. I was trying to do something similar, when I came across your question. After a little trial and error, I have found that there can be no code prior to the #include directive for the precompiled header when using the /Yu compiler option.
#ifdef USES_PCH
#include "stdafx.h"
#endif
result: fatal error C1020: unexpected #endif
As far as I know, it can't, but there are some heuristics: VC++ uses StdAfx.h, Borland uses #pragma hdrstop, etc.