Setting label text from other header files in Visual C++ 2010 .rc file - visual-studio-2010

Assume that you have a label in a legacy Visual C++ 2010 project, defined like so:
[foo.rc]
LTEXT "Foo",IDC_STATIC,42,42,42,42
In a resource (.rc) file.
Now, you want to generate the text based on constants you define in a header file, like so:
[foo.rc]
LTEXT FOO_TEXT,IDC_STATIC,42,42,42,42
Where FOO_TEXT was previously defined in some other way, for instance:
[bar.h]
#define FROBNICATE "F"
#define OO "o"
#define ICANTTHINKOFMETASYNTACTICVARIABLESBEGINNINGWITHO "o"
#define FOO_TEXT (FROBNICATE OO ICANTTHINKOFMETASYNTACTICVARIABLESBEGINNINGWITHO)
Only that that doesn't work, because .rc files are not header files, and the RC compiler complains, telling you:
[Build output]
1>foo.rc(42): error RC2116: expecting number for ID
1>
1>
1>foo.rc(42): error RC2108: expected numerical dialog constant
What would you do?
To clarify, yes, the entire string in question is known at compile-time, but it also needs to be constructed from smaller strings (in this case, version information and release category (development, release, and another one)). Of course, I could also write C++ code that does that, but that seems very inelegant to me.
So, is there a nicer way?

I don't think you will be able to achive what you want without C++ code. See the comment to this msdn article:
Don't use parens in #define
The resource compiler is very limited in its understanding of directives. So, for example, this:
#define RESTYPE_FILE (256)
will silently get ignored, while this:
#define RESTYPE_FILE 256
will work. Obviously, trying to use expressions or anything complicated like that will silently fail, leaving you wondering why you can't load that resource.

Related

ESP32 compiler giving "multiple definition of" errors

Got a new issue I've not come across before that's appeared when using the Espressif ESP32 ESP-IDF standard setup under VSCode. It uses the GNU compiler.
I'm getting "multiple definition of" errors on variables that share the same name, but which should be local.
So I use a .c and .h pair of files approach.
In my .c files I do this at the top
#define IO_EXPANDER_C //<<<This is a unique define for this file pair
#include "io-pca9539.h"
In my .h files I do this:
#ifdef IO_EXPANDER_C
//----- INTERNAL ONLY MEMORY DEFINITIONS -----
uint8_t *NextReadDataPointer;
//----- INTERNAL & EXTERNAL MEMORY DEFINITIONS -----
//(Also defined below as extern)
int SomeVariableIWantAvailableGlobally;
#else
//----- EXTERNAL MEMORY DEFINITIONS -----
extern int SomeVariableIWantAvailableGlobally;
#endif
It's a great simple system, any other .c file that includes the .h file (without the #define above its include statemnt), gets all of its extern variables, none of its local variables.
But, compiling in VSCode with my ESP-IDF based project, I'm getting "multiple definition of" errors relating to "NextReadDataPointer"
I use the same variable name NextReadDataPointer in another file pair in just the same way, but it's never declared anywhere as extern and each file pair uses a separate #define (IO_EXPANDER_C and LED_C). I do this all the time normally and I can't see any obvious mistakes.
I've never seen a C compiler do this before, it's as if it's mixing up the local definitions somehow. A #define should only have scope in the file it is declared in and in any includes within that file.
Even odder, the error is not generated if the project is built but a function is called from just one of the file pairs that share the same local variable name. It's only generated when functions are called from both file pairs from my main application.
Can anyone shed light on whether the GNU C compiler does something funky for a standard ESP-IDF project as it's got me baffled?
uint8_t *NextReadDataPointer; creates a variable which is visible across all translation units, i.e. it's the opposite of "private". If you include this header in multiple c files and the linker tries to link those together; it'll see a conflict. The keyword you're looking for is static, for example static uint8_t *NextReadDataPointer; creates a variable that is not visible across translation units. The reason you don't see the problem if calling a function from only one of those two files is because in this case the linker doesn't bother looking into the other one.
Personally I'd avoid such clever preprocessor hacks because it's quite difficult to see how files include one another and debug the resulting problems. I'd suggest sticking to the standard way of declaring shared things in header files and keeping the private stuff inside the c file (prepended by static).

Qt Creator : Intellisense for C, force a given context

So I have Qt Creator 7.0.2. The editor parses and colors and does lots of things with a given file, using the environment and the other files included.
However for header files, it does not take into account that this file is included in some compilation unit which provides some preexisting context (macros or types declared, other files already included, etc.) . Of course, one of the reasons for that is that there are multiple possibilities, but I do not know if Qt Creator offers a way to choose a context for parsing that would match one of those possibilities. Let me give an example with macros.
The file I am viewing in the editor : header.h
#ifdef A
/* Declarations in case of A */
#endif
#ifdef B
/* Definitions in case of B */
#endif
When viewing header.h in the editor, both paragraphs (in case of A, in case of B) are grayed out because in the context of header.h alone Qt Creator / Intellisense does not see a definition of A or B - and fair enough !
A compilation unit that includes this file : compilation_unit_A.c
#define A
#include "header.h"
/* Code using the definitions from the header file in case of A */
Another compilation unit that includes this file : compilation_unit_B.c
#define B
#include "header.h"
/* Code using the definitions from the header file in case of B */
I would like Qt Creator to offer me two options for parsing : in the context of compilation_unit_A.c or in the context of compilation_unit_B.c.
Then one or the other paragraph would not be grayed out and instead parsed like normal code, because one or the other of A and B would be defined.
In my case, definitions for A and B are themselves found in other header files included in each compilation unit, but if Qt Creator / Intellisense starts looking into the preexisting code in compilation_unit_A/B.c then it would also naturally open other header files to construct a context - like it already does.
EDIT : alternatively, I have one header file that, if "pretend-included" as part of the context, would cover almost everything. Can I ask Qt Creator to include all the contents of a given header file in its parsing for the editor ?

What is this apparently non-standard struct packing syntax fed into GCC?

I am a little bit dumbstruck by some code that is associated with a 3rd-party code base I'm working with. All code is written in C or assembler except for a number of files adhering to the syntax described below. I cannot find any documentation on this syntax yet GCC swallows it without any problem. It's GCC 8 I work with. The syntac must be some extension to GCC. It would be very nice if somebody could enlighten me as to exactly what extension it is and where it is documented.
The code obviously defines struct types with packing and uses syntax like this:
Comment lines begin with "--"
Keywords are "block", "padding", "field", and "field_high", possibly more. A typical piece of code looks like this:
block <BLOCK_NAME> {
field <FIELD_NAME_NO_1> 1
field <FIELD_NAME_NO_2> 1
padding 8
field_high <FIELD_NAME_NO_3> 6
}
A block can contain any number of fields and paddings. The numbers given always add up to a word length on the target architecture.
Files containing this kind of code most often have ".bf" es their extension while ".c" can occur too. Some files have #include's referring to ordinary C headers while some ordinary C files have #includes referring to ".bf" files.
A quick glance at the tools directory in the Git repository found me bitfield_gen.py, which claims to be a code generator for "bitfield structures". I presume that's what .bf stands for.
There are some CMake functions for building bitfield targets in tools/helpers.cmake. That will probably make sense to people more familiar with CMake than I am.
The Bit Field Generator is documented here http://research.davidcock.fastmail.fm/papers/Cock_08.pdf

What does this preprocessor line mean?

I am working on a project with the library ADOL-C (for automatic differentiation) using gcc. Right now I am trying to recompile the library to use the parallelization features however the make process does not working apparently due to some preprocessor stuff.
I think the problematic line is :
#define ADOLC_OPENMP_THREAD_NUMBER int ADOLC_threadNumber
However I could not find what it means. Does it make a link between two variables? Also ADOLC_threadNumber has not been declared before...
The preprocessor doesn't even know what a variable is. All that #define does is define a short(long?)hand for declaring a variable. I.e., if you type
ADOLC_OPENMP_THREAD_NUMBER;
It becomes
int ADOLC_threadNumber;
It's just a text substitution. Everywhere in code where ADOLC_OPENMP_THREAD_NUMBER appears, it's substituted by int ADOLC_threadNumber.
As far as I see it, the line with the define itself is not problematic, but maybe the subsequent appearance of ADOLC_OPENMP_THREAD_NUMBER. However, to check this, we need to know more about the context.
#define is a directive used often in .h files,
it creates a macro, which is the association of an identifier or parameterized identifier with a token string.
After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.
#define may be associated with #ifndef directive to avoid to delare the identifier more than once :
#ifndef ADOLC_OPENMP_THREAD_NUMBER
#define ADOLC_OPENMP_THREAD_NUMBER int ADOLC_threadNumber
#endif

Is there a way to automatically #define header files in visual studio?

Since it's petty much mandatory that you do this, it seems like thered be a way to just have it done automatically. It'd save a lot of time.
You can write your own templates that include these declarations.
An alternative is to write some code snippets to ease insertion of header #define declarations.
You can't have preprocessor directives that expand into other preprocessor directives.
But you can have a header that includes all the headers you need, and include only one header wherever you like.
Note that this might slow down compilation time, since the translation units will get bigger.

Resources