I have written a minimum class to better submit my problem.
I have three files:
1) test.hpp
#include <cstdlib>
#include <stdio.h>
#include <map>
class test {
public:
test () {}
~test () {}
const char *getPin (const char *);
private:
static const std::map<const char *, const char *> pinIndex;
static std::map<const char *, const char *> initializePins ();
};
2) test.cpp
#include "test.hpp"
const std::map<const char *, const char *> test::pinIndex = test::initializePins ();
std::map<const char *, const char *> test::initializePins () {
std::map<const char *, const char *> pins;
pins.insert (
std::pair<const char *, const char *> (
"AAAA", "BBBB"
)
);
return pins;
}
const char *test::getPin (const char *pinNumber) {
if (pinIndex.count (pinNumber) > 0) {
return pinIndex.at (pinNumber);
}
else {
printf ("Undefined pin %s!\n", pinNumber);
exit (EXIT_FAILURE);
}
}
3) main.cpp
#include "test.hpp"
int main () {
test myExample;
const char *a = myExample.getPin ("AAAA");
exit (EXIT_SUCCESS);
}
When I compile and run it I get this error:
Undefined pin AAAA!
If I remove main.cpp and put the main function in test.cpp file, I do not get me any error and GetPin returns the correct value.
Any idea what I'm doing wrong?
Thank you
Your problem is that you're using char*
pointers in your map as key values. To find entries in the map, the implementation uses comparison operations (<
) for the given key.
If you're going to compare char*
pointers those will almost never be the same, and are completely unrelated to their contents, which is what you're actually want to look for.
A simple solution for your problem would be to change your map type to
std::map<std::string, std::string>
Another possible solution is to provide a class that compares two char*
pointers based on content as the 3rd template parameter of the map
std::map<char*, char*, MyComparer>
where MyComparer
is s.th. like this
struct MyComparer {
bool operator()( const char*& lhs, const char*& rhs ) const {
return strcmp(lhs,rhs) < 0;
}
};
As an explanation why you experience that seemingly inconsistent behavior, when moving your test to a separate compilation unit:
If you have the same string literals (e.g. "AAAA"
) appearing in the TU multiple times, the compiler can optimize them to be stored just once, and thus you'll have the same address for all of their appearances.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments