Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid global variables/methods name clashes when using C headers in C++

Tags:

c++

namespaces

I recently spent some time chasing an annoying little bug and I'm looking for suggestions for those of you who have either encountered the same problem or know the best way to avoid it.

I have a situation where I am developing in C++ and using strerror and as a result I am using something similar to

extern "C" {
#include <string.h>
}

(Same situation for #include <cstring>, btw). Now, there is a function defined in that file as follows: extern char *index (__const char *__s, int __c) This function lead to the fun I had where I originally had a construct similar to:

for (int index = 0; index != condition (); ++index) {
   // do something with buffer[index] here
}

log->write ("Final value of index: %d\n", index); // <- Ooops!!!

But instead of getting a compile error I get bogus output. I have my compiler (g++) flags set pretty high and the following did not catch this:

-W -Wall -Wextra -Werror -Wshadow -Wformat -pedantic -ansi

I can also not use an #undef trick like in <cstring> because this is not a macro.

My question is whether or not others have encountered this same problem and what is the best solution to it? Ideally, I'd love to hear about some obscure g++ functionality like -use-the-force-luke=... ;)

Note that I'm not asking how to solve this exact problem; I could just change the variable name. I'm looking for tips on how to avoid this situation in the future.

EDIT:

Due James Curran's reply I think I should clarify a bit. I'm not looking at why this should not happen. I understand that in the absence of local variables the scope space is extended. What I am surprised about is that there is no flag I can set that warns about this. I'd think that -Wshadow would catch it since it catches variable/method shadowing within a class scope, but I digress.

What I am interested in is a way to have a notification that a local name is in conflict with a non-local scope. There is mention that I would have caught this particular bug had I used stream operations instead of variadic calls. True enough, but even the following will not produce warnings/errors with g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-51) and the following flags -W -Wall -Wextra -Werror -Wshadow -ansi -pedantic.

#include <iostream>
#include <cstring>

int main () {
        int index = 42;
        std::cerr << index << std::endl;
        return 0;
}

That is curious to me.

like image 992
ezpz Avatar asked Apr 15 '26 21:04

ezpz


1 Answers

First, it looks like you are using printf style variadic argument list which causes an immediate loss of type safety. You should probably avoid this sort of design in C++.

If you have to do this, then you could consider decorating the function declaration to tell gcc that it is a printf-like function and it will then give you warnings if your argument list doesn't match your format string as it does for the standard *printf functions.

E.g.

void write(const char* f, ...) __attribute__((format (printf, 2, 3)));
like image 68
CB Bailey Avatar answered Apr 17 '26 12:04

CB Bailey



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!