6 ms·
Nah, it's true. Here's dumb example, where the compiler errors totally miss make_unique: #include <memory> #define u8 }{ struct Foo { char const *foo(
by wfunction 9y ago
Nah, it's true. Here's dumb example, where the compiler errors totally miss make_unique:
#include <memory>
#define u8 }{
struct Foo {
char const *foo() {
char const *r = u8"foo";
std::make_unique<int>(1);
return r;
}
};
Maybe now you can argue it won't happen in practice, and my intuition is you'd still be wrong for large projects, but I don't have the time to try to come with a more realistic example. Hopefully this is enough to get the point across though. The syntax has changed, and the compiler can be only so smart trying to decipher it efficiently.
- rhaps0dy 9y agoOops. What a mess of features.
- geezerjay 9y ago> Here's dumb example, where the compiler errors totally miss make_unique: Sounds like you've found a bug in GCC. Why not report it?
- wfunction 9y agoDoesn't sound like it to me... I don't consider it a bug. I don't think it's even solvable in general. In fact I think GCC is being quite generous in going out of its way to report things so nicely already.
- geezerjay 9y agoHere's another example: Test code: #include <memory> int main() { std::unique_ptr<int> pPointer = std::make_unique<int>(); return 0; } Here's the GCC output (v4.9.2) with C++14: geezerjay@debian:tmp$ g++ --std=c++14 main.c++ geezerjay@debian:tmp$ And now the GCC output with C++11: geezerjay@debian:tmp$ g++ --std=c++14 main.c++ main.c++: In function ‘int main()’: main.c++:5:34: error: ‘make_unique’ is not a member of ‘std’ std::unique_ptr<int> pPointer = std::make_unique<int>(); ^ main.c++:5:51: error: expected primary-expression before ‘int’ std::unique_ptr<int> pPointer = std::make_unique<int>(); geezerjay@debian:tmp$ Perhaps recent GCC versions catch this issue, but errors are indeed thrown if make_unique, a C++14 feature, is present while compiling C++11 code.
- deleted 9y ago[deleted]
- lorenzhs 9y agoI wouldn't blame the compiler for missing make_unique in that scenario. Rather it would be nice if compilers warned that u8"foo" is a C++11 construct and any errors following could be due to it not existing in C++03. It never gets to the make_unique because there's another error before it. In C++11 mode, both g++ and clang++ (I tested 6 and 3.8, respectively) complain about make_unique not being a member of std, as expected.
- wfunction 9y ago> I wouldn't blame the compiler I'm not blaming anybody/anything though > It never gets to the make_unique because there's another error before it. Yes, that was literally the entire point of this example, because the prior commenter had said that GCC doesn't stumble on parsing errors and keeps going anyway.
- lorenzhs 9y agoAh, right, I might have misunderstood you there. This is a bit of a special case though, as the preprocessor for C++03 messes up the code so badly that a later parser trips, and it never even gets to the pass that resolves identifiers because a critical error is raised before. Maybe then the preprocessor could emit warnings when replacing tokens it knows to be keywords in later standard versions. It likely isn't that easy, though, as emitting helpful warnings would probably require parsing some of the surrounding code, which hasn't happened yet, so the potential for false positives is large.
- wfunction 9y agoSigh, I knew someone was going to just complain that this is using the preprocessor and I'd have to waste more time on this... (a) It's a fundamental (but common) mistake to view processing as a logically "separate" stage from compiling C++ code. The two are semantically intertwined for all intents and purposes. Trivial example: the value of std::numeric_limits<int>::max() MUST match that of INT_MAX. Another trivial example: #pragmas (like omp parallel or vectorize) are "preprocessor" directives that can't really be "preprocessed"; they're often tightly coupled to the actual code. You cannot preprocess a program with a compiler that differs in any semantically visivle way from the actual compiler and expect the program to behave as the C++ standard specifies. The correct way to see a preprocessed file is as a convenient text-format snapshot/dump of the compiler's memory in the overall compilation process, nothing more. (b) I don't want to spend more time on this but I'm pretty sure you could find a counterexample that doesn't depend on the preprocessor if you try hard enough. Just pretend I'm claiming the opposite and you're arguing with me about that, trying to prove me wrong. I'm sure you'll find a counterexample. Look at >> vs. > > and the like if you have no idea where to start.