I am puzzled by following difference discovered by trying to replicate different bug. This program works as expected:
#include <memory>
#include <string>
#include <iostream>
int main() {
std::string s = "Hi\n";
std::cout << s;
auto p = std::make_unique<const char *>(s.c_str());
std::cout << *(p.get());
return 0;
}
It prints
Hi
Hi
But adding single volatile
keyword:
#include <memory>
#include <string>
#include <iostream>
int main() {
std::string s = "Hi\n";
std::cout << s;
auto p = std::make_unique<volatile const char *>(s.c_str());
std::cout << *(p.get());
return 0;
}
makes it print:
Hi
1
This did not help either:
#include <memory>
#include <string>
#include <iostream>
int main() {
std::string s = "Hi\n";
std::cout << s;
auto p = std::make_unique<volatile const char *>(reinterpret_cast<volatile const char *>(s.c_str()));
std::cout << *(p.get());
return 0;
}
Why?
The answer is in the comment by Jarod42:
std::ostream
has overload for operator<<
forconst char*
andbool
(pointer has conversion tobool
), not forvolatile const char *
The difference then can be replicated simply by:
#include <iostream>
int main() {
/*volatile*/ const char * s = "abc\n";
std::cout << s;
return 0;
}
Gives abc
with volatile
commented out and 1
(without newline) with uncommenting it.