While everything has effectively been said above, here's how I go about such errors:
First I use an online compiler. My preference is
GDB online Debugger | Compiler - Code, Compile, Run, Debug online C, C++[
^]. It can compile in C and various variants of C++.
Next I try a trimmed down code segment adjusted to not depend on any OS specific stuff:
#include <stdio.h>
char* envVarStrings[] = { "a", "b" };
#define ENV_VAR_STRING_COUNT (sizeof(envVarStrings)/sizeof(char *))
int main() {
printf("# strings: %d", ENV_VAR_STRING_COUNT);
return 0;
}
When I try to run this segment the compiler states
Quote:
warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
Following up on that warning I've found this :
warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings] - Stack Overflow[
^].
According to this there is indeed a const missing, as OG already suspected:
char const* envVarStrings[] = { "a", "b" };
This line is accepted without warning.
Of course, for the same reason you must also change your macro to use a const char pointer.
The next error reported in my test code is that I was trying to use your macro as an int, so I added a type cast to int as well, but that may not be necessary in your code.
Lastly, like Shao Voon Woong pointed out in a comment to solution 1, any attempt to pass one of the string literals to a function must also use const char pointers.
The following example runs without warnings or errors:
#include <stdio.h>
const char* envVarStrings[] = { "a", "b" };
#define ENV_VAR_STRING_COUNT (int)(sizeof(envVarStrings)/sizeof(const char *))
void printError(const char* text)
{
printf("error: %s\n", text);
}
int main() {
printf("# strings: %d\n", ENV_VAR_STRING_COUNT);
printError(envVarStrings[0]);
return 0;
}
Of course, you could simply choose to compile all this as C code and forget about the fine print: you might get some warnings but it should compile. ;-p In fact, I've wondered why you are using a macro instead of a const? It's obvious this is a constant, and that's what const is for - unless you are compiling C code!
Tl.dr: if you want C code, it should work (with warnings, depending on the version). Otherwise, you shouldn't use that macro! Not that this would have saved you from the error, but at least you'd have more concise information for locating the actual issue. Moreover, using modern concepts and C++ language features you could have avoided these issues:
#include <iostream>
#include <string>
std::string envVarStrings[] = { "a", "b" };
const int ENV_VAR_STRING_COUNT = (sizeof(envVarStrings)/sizeof(std::string));
void printError(std::string& text)
{
std::cout << "Error: " << text << std::endl;
}
int main() {
std::cout << "# strings: " << ENV_VAR_STRING_COUNT << std::endl;
printError(envVarStrings[0]);
return 0;
}
Note that although printError should use a const argument, omiting it is not a problem here! The reason is that std::string hides the ugly details causing the issues you had, and the string type itself is rather more forgiving and easy to use!