How to avoid 'not declared' error in old template-heavy library without changing all the code to use this->?
I'm getting "was not declared in this scope" errors when trying to compile a library containing heavily templated code. It seems like the code was developed using gcc-2.95, and (as I was told) did compile about four years ago. As I found on StackOverflow and the C++-FAQ the code is indeed expected to fail, and seems to rely on non-conforming compilation.
Minimal reproduction example, compile with gcc -c example.cpp:
// file: example.cpp
template <typename T>
class Base
protected:
int i;
;
template <typename T>
class Derived : protected Base<T>
public:
void f()
// i = 5; // Error: i was not declared in this scope
this->i = 5; // compiles
;
My question is: How do I compile this library using more recent compilers?
The library code uses the faulty syntax (i=5) all over the place, so I'd prefer to avoid manually changing the whole library to 'this->i=5'. The provided links suggest 'using' statements, but while that would reduce my work, my preferred method would involve no code changes, but forcing the compiler into the old behaviour of 'assuming this' on these variables. I could not find a compiler-switch for this situation, -std=c++98, -fpermissive etc. didn't work.
Quote from the C++-FAQ:
Perhaps surprisingly, the following code is not valid C++, even though some compilers accept it:
I also tried using CLang++, with the same results. Which compilers would accept this code without changes?
Edit: Added info on -fpermissive, as Brian suggested
c++ templates gcc legacy-code
add a comment |
I'm getting "was not declared in this scope" errors when trying to compile a library containing heavily templated code. It seems like the code was developed using gcc-2.95, and (as I was told) did compile about four years ago. As I found on StackOverflow and the C++-FAQ the code is indeed expected to fail, and seems to rely on non-conforming compilation.
Minimal reproduction example, compile with gcc -c example.cpp:
// file: example.cpp
template <typename T>
class Base
protected:
int i;
;
template <typename T>
class Derived : protected Base<T>
public:
void f()
// i = 5; // Error: i was not declared in this scope
this->i = 5; // compiles
;
My question is: How do I compile this library using more recent compilers?
The library code uses the faulty syntax (i=5) all over the place, so I'd prefer to avoid manually changing the whole library to 'this->i=5'. The provided links suggest 'using' statements, but while that would reduce my work, my preferred method would involve no code changes, but forcing the compiler into the old behaviour of 'assuming this' on these variables. I could not find a compiler-switch for this situation, -std=c++98, -fpermissive etc. didn't work.
Quote from the C++-FAQ:
Perhaps surprisingly, the following code is not valid C++, even though some compilers accept it:
I also tried using CLang++, with the same results. Which compilers would accept this code without changes?
Edit: Added info on -fpermissive, as Brian suggested
c++ templates gcc legacy-code
Have you tried-fpermissive?
– Brian
Nov 11 at 17:29
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
4
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
1
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52
add a comment |
I'm getting "was not declared in this scope" errors when trying to compile a library containing heavily templated code. It seems like the code was developed using gcc-2.95, and (as I was told) did compile about four years ago. As I found on StackOverflow and the C++-FAQ the code is indeed expected to fail, and seems to rely on non-conforming compilation.
Minimal reproduction example, compile with gcc -c example.cpp:
// file: example.cpp
template <typename T>
class Base
protected:
int i;
;
template <typename T>
class Derived : protected Base<T>
public:
void f()
// i = 5; // Error: i was not declared in this scope
this->i = 5; // compiles
;
My question is: How do I compile this library using more recent compilers?
The library code uses the faulty syntax (i=5) all over the place, so I'd prefer to avoid manually changing the whole library to 'this->i=5'. The provided links suggest 'using' statements, but while that would reduce my work, my preferred method would involve no code changes, but forcing the compiler into the old behaviour of 'assuming this' on these variables. I could not find a compiler-switch for this situation, -std=c++98, -fpermissive etc. didn't work.
Quote from the C++-FAQ:
Perhaps surprisingly, the following code is not valid C++, even though some compilers accept it:
I also tried using CLang++, with the same results. Which compilers would accept this code without changes?
Edit: Added info on -fpermissive, as Brian suggested
c++ templates gcc legacy-code
I'm getting "was not declared in this scope" errors when trying to compile a library containing heavily templated code. It seems like the code was developed using gcc-2.95, and (as I was told) did compile about four years ago. As I found on StackOverflow and the C++-FAQ the code is indeed expected to fail, and seems to rely on non-conforming compilation.
Minimal reproduction example, compile with gcc -c example.cpp:
// file: example.cpp
template <typename T>
class Base
protected:
int i;
;
template <typename T>
class Derived : protected Base<T>
public:
void f()
// i = 5; // Error: i was not declared in this scope
this->i = 5; // compiles
;
My question is: How do I compile this library using more recent compilers?
The library code uses the faulty syntax (i=5) all over the place, so I'd prefer to avoid manually changing the whole library to 'this->i=5'. The provided links suggest 'using' statements, but while that would reduce my work, my preferred method would involve no code changes, but forcing the compiler into the old behaviour of 'assuming this' on these variables. I could not find a compiler-switch for this situation, -std=c++98, -fpermissive etc. didn't work.
Quote from the C++-FAQ:
Perhaps surprisingly, the following code is not valid C++, even though some compilers accept it:
I also tried using CLang++, with the same results. Which compilers would accept this code without changes?
Edit: Added info on -fpermissive, as Brian suggested
c++ templates gcc legacy-code
c++ templates gcc legacy-code
edited Nov 11 at 20:32
asked Nov 11 at 17:29
DocDrum
113
113
Have you tried-fpermissive?
– Brian
Nov 11 at 17:29
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
4
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
1
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52
add a comment |
Have you tried-fpermissive?
– Brian
Nov 11 at 17:29
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
4
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
1
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52
Have you tried
-fpermissive?– Brian
Nov 11 at 17:29
Have you tried
-fpermissive?– Brian
Nov 11 at 17:29
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
4
4
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
1
1
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52
add a comment |
1 Answer
1
active
oldest
votes
Unfortunately, as @Mat said in the comments, the only viable alternative here is to correct the code (and you've shown you already know how to do that).
This is a result of two-phase name lookup, so to get a compiler to accept it, you need one that doesn't implement two-phase name lookup. With Microsoft's compiler you can use the -Zc:twoPhase- flag to get the old behavior with the current compiler (i.e., to get the compiler to accept your code as-is).
g++ had two-phase name lookup reasonably correct starting with g++ 4.7 if memory serves. I'd be pretty confident that all the g++ 3.x series will still accept your code, and early g++ 4.x probably will as well, but I'm pretty sure g++ 4.7 and later will reject it.
As for Clang--if memory serves, it had two-phase name lookup from the beginning. Early versions undoubtedly had some bugs, so it's barely possible one of them might allow this, but I kind of doubt it--this is pretty much the classic demonstration of when two-phase name lookup broke existing code, so any compiler that tries to implement two-phase name lookup almost certainly has a test case similar to this.
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251331%2fhow-to-avoid-not-declared-error-in-old-template-heavy-library-without-changing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Unfortunately, as @Mat said in the comments, the only viable alternative here is to correct the code (and you've shown you already know how to do that).
This is a result of two-phase name lookup, so to get a compiler to accept it, you need one that doesn't implement two-phase name lookup. With Microsoft's compiler you can use the -Zc:twoPhase- flag to get the old behavior with the current compiler (i.e., to get the compiler to accept your code as-is).
g++ had two-phase name lookup reasonably correct starting with g++ 4.7 if memory serves. I'd be pretty confident that all the g++ 3.x series will still accept your code, and early g++ 4.x probably will as well, but I'm pretty sure g++ 4.7 and later will reject it.
As for Clang--if memory serves, it had two-phase name lookup from the beginning. Early versions undoubtedly had some bugs, so it's barely possible one of them might allow this, but I kind of doubt it--this is pretty much the classic demonstration of when two-phase name lookup broke existing code, so any compiler that tries to implement two-phase name lookup almost certainly has a test case similar to this.
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
add a comment |
Unfortunately, as @Mat said in the comments, the only viable alternative here is to correct the code (and you've shown you already know how to do that).
This is a result of two-phase name lookup, so to get a compiler to accept it, you need one that doesn't implement two-phase name lookup. With Microsoft's compiler you can use the -Zc:twoPhase- flag to get the old behavior with the current compiler (i.e., to get the compiler to accept your code as-is).
g++ had two-phase name lookup reasonably correct starting with g++ 4.7 if memory serves. I'd be pretty confident that all the g++ 3.x series will still accept your code, and early g++ 4.x probably will as well, but I'm pretty sure g++ 4.7 and later will reject it.
As for Clang--if memory serves, it had two-phase name lookup from the beginning. Early versions undoubtedly had some bugs, so it's barely possible one of them might allow this, but I kind of doubt it--this is pretty much the classic demonstration of when two-phase name lookup broke existing code, so any compiler that tries to implement two-phase name lookup almost certainly has a test case similar to this.
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
add a comment |
Unfortunately, as @Mat said in the comments, the only viable alternative here is to correct the code (and you've shown you already know how to do that).
This is a result of two-phase name lookup, so to get a compiler to accept it, you need one that doesn't implement two-phase name lookup. With Microsoft's compiler you can use the -Zc:twoPhase- flag to get the old behavior with the current compiler (i.e., to get the compiler to accept your code as-is).
g++ had two-phase name lookup reasonably correct starting with g++ 4.7 if memory serves. I'd be pretty confident that all the g++ 3.x series will still accept your code, and early g++ 4.x probably will as well, but I'm pretty sure g++ 4.7 and later will reject it.
As for Clang--if memory serves, it had two-phase name lookup from the beginning. Early versions undoubtedly had some bugs, so it's barely possible one of them might allow this, but I kind of doubt it--this is pretty much the classic demonstration of when two-phase name lookup broke existing code, so any compiler that tries to implement two-phase name lookup almost certainly has a test case similar to this.
Unfortunately, as @Mat said in the comments, the only viable alternative here is to correct the code (and you've shown you already know how to do that).
This is a result of two-phase name lookup, so to get a compiler to accept it, you need one that doesn't implement two-phase name lookup. With Microsoft's compiler you can use the -Zc:twoPhase- flag to get the old behavior with the current compiler (i.e., to get the compiler to accept your code as-is).
g++ had two-phase name lookup reasonably correct starting with g++ 4.7 if memory serves. I'd be pretty confident that all the g++ 3.x series will still accept your code, and early g++ 4.x probably will as well, but I'm pretty sure g++ 4.7 and later will reject it.
As for Clang--if memory serves, it had two-phase name lookup from the beginning. Early versions undoubtedly had some bugs, so it's barely possible one of them might allow this, but I kind of doubt it--this is pretty much the classic demonstration of when two-phase name lookup broke existing code, so any compiler that tries to implement two-phase name lookup almost certainly has a test case similar to this.
answered Nov 11 at 18:06
Jerry Coffin
382k48464907
382k48464907
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
add a comment |
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
This is valuable information, thanks for the explanation! we had gcc-4.4 installed until lately, possibly that's the version that was reported as working. I'll try to get a local 4.4 install, before patching in hundreds of 'this->'.
– DocDrum
Nov 11 at 21:17
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251331%2fhow-to-avoid-not-declared-error-in-old-template-heavy-library-without-changing%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Have you tried
-fpermissive?– Brian
Nov 11 at 17:29
@πάντα ῥεῖ: that dup seems completely unrelated, this is a dependent name lookup issue or something like that
– Mat
Nov 11 at 17:32
4
@DocDrum: fix your code. That's the only viable solution for using modern compilers.
– Mat
Nov 11 at 17:33
1
One cannot assume that code is correct and just because it compiled. Even if the compiler has a bug and allows this, there are no guarantees you'll get a usable program.
– user4581301
Nov 11 at 17:52