Take this: ---------------- struct X { void operator++(); }; int main () { X x; x++; } --------------- Since there is indeed no postfix operator++ declared, the code is invalid, but we get a strange error message: g/x> /home/bangerth/tmp/gcc/b35/gcc/cc1plus -quiet -O2 xx.cc xx.cc: In function `int main()': xx.cc:5: error: no `operator++(int)' declared for postfix `++', trying prefix operator instead What does the compiler mean when it says "Trying prefix operator instead"? Does this imply that if there is one then it would use it? Hopefully not. However, if I remove the prefix form as well, i.e. do this: -------------------- struct X {}; int main () { X x; x++; } -------------------- then I get this instead: g/x> /home/bangerth/tmp/gcc/b35/gcc/cc1plus -quiet -O2 xx.cc xx.cc: In function `int main()': xx.cc:5: error: no `operator++(int)' declared for postfix `++', trying prefix operator instead xx.cc:5: error: no match for 'operator++' in '++x' Now, I think that's completely bogus: we do have a syntax error here, so why is the compiler pretending it is trying to find a way around it for me? If it said, as a note: Note: the class declares a prefix operator++ instead then that would be fine, but the message that it is trying something else instead is too much AI for me... This behavior has been with us since at least 2.95. W.
I think there is a couple of missing words, "to use". So it should read "xx.cc:5: error: no `operator++(int)' declared for postfix `++', trying to use prefix operator instead". But you are right, this is bogus, maybe the problem is that we used (or still do with -fpremisive) try to use prefix version of the operators.
Subject: Re: Strange message when operator++ not found > But you are right, this is bogus, maybe the problem is that we used (or > still do with -fpremisive) try to use prefix version of the operators. Well, I sure hope we don't! W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
It is special cased: case POSTINCREMENT_EXPR: case POSTDECREMENT_EXPR: /* Look for an `operator++ (int)'. If they didn't have one, then we fall back to the old way of doing things. */ if (flags & LOOKUP_COMPLAIN) pedwarn ("no `%D(int)' declared for postfix `%s', trying prefix operator instead", fnname, operator_name_info[code].name); if (code == POSTINCREMENT_EXPR) code = PREINCREMENT_EXPR; else code = PREDECREMENT_EXPR; result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE, overloaded_p); which means -fpermissive does look do the transformation. :( Why we do this is unknown as it comes from PRE EGCSE (aka CVS days).
Subject: Re: Strange message when operator++ not found > which means -fpermissive does look do the transformation. But I didn't specify -fpermissive. Why is it trying anyway? The code you show doesn't even seem to check for this flag, does it? W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
No it does not but pedwarn does so it turns it into an error which is why there is an error and not a warning.
Subject: Re: Strange message when operator++ not found But the code after it that turns a postfix into a prefix operator isn't guarded on that... W. ------------------------------------------------------------------------- Wolfgang Bangerth email: bangerth@ices.utexas.edu www: http://www.ices.utexas.edu/~bangerth/
Pre-1985 C++ didn't distinguish between prefix and postfix ++ and operator++() was used for both.
Subject: Re: Strange message when operator++ not found > Pre-1985 C++ :-)) I thought I was old already, but apparently not old enough... W.
Also occurs in 4.2 and 4.3 Discussed here: http://lists.boost.org/Archives/boost/2002/03/27238.php http://lists.boost.org/Archives/boost/2002/03/27274.php Seems to end with this: http://lists.boost.org/Archives/boost/2002/03/27355.php I'm going to try it on the newest version of Boost from the authors site: Boost C++ Libraries - 1.34.0 http://sourceforge.net/project/showfiles.php?group_id=7586
I compiled the program I was working on using GCC 4.2 that was configured using the option "--enable-concept-checks" and one file would not compile; giving this error: /usr/include/c++/4.2/bits/boost_concept_check.h: In member function 'void __gnu_cxx::_InputIteratorConcept<_Tp>::__constraints() [with _Tp = profile_t::const_iterator]': /usr/include/c++/4.2/bits/boost_concept_check.h:63: instantiated from 'void __gnu_cxx::__function_requires() [with _Concept = __gnu_cxx::_InputIteratorConcept<profile_t::const_iterator>]' /usr/include/c++/4.2/bits/stl_numeric.h:84: instantiated from '_Tp std::accumulate(_InputIterator, _InputIterator, _Tp) [with _InputIterator = profile_t::const_iterator, _Tp = long long unsigned int]' /usr/include/c++/4.2/bits/boost_concept_check.h:456: error: no 'operator++(int)' declared for postfix '++', trying prefix operator instead I recompiled that one file only using GCC 4.3 that was configured WITHOUT using the option "--enable-concept-checks" and the file compiled fine. I ran "make check" and all tests passed. I did some searching for the use of concept checks, first on my installed files: # grep -r GLIBCXX_CONCEPT_CHECKS /usr/include/* /usr/include/c++/4.2/bits/concept_check.h:#ifndef _GLIBCXX_CONCEPT_CHECKS /usr/include/c++/4.2/bits/c++config.h:#define _GLIBCXX_CONCEPT_CHECKS 1 Binary file /usr/include/c++/4.2/bits/stdc++.h.gch/O0g.gch matches Binary file /usr/include/c++/4.2/bits/stdc++.h.gch/O2g.gch matches Binary file /usr/include/c++/4.2/bits/stdtr1c++.h.gch/O2g.gch matches /usr/include/c++/4.2/i686-pc-linux-gnu/bits/c++config.h:#define _GLIBCXX_CONCEPT_CHECKS 1 Binary file /usr/include/c++/4.2/i686-pc-linux-gnu/bits/stdc++.h.gch/O0g.gch matches Binary file /usr/include/c++/4.2/i686-pc-linux-gnu/bits/stdc++.h.gch/O2g.gch matches Binary file /usr/include/c++/4.2/i686-pc-linux-gnu/bits/stdtr1c++.h.gch/O2g.gch matches /usr/include/c++/4.1.2/bits/concept_check.h:#ifndef _GLIBCXX_CONCEPT_CHECKS /usr/include/c++/4.1.2/i486-linux-gnu/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ /usr/include/c++/4.1.2/i486-linux-gnu/64/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ /usr/include/c++/3.4/bits/concept_check.h:#ifndef _GLIBCXX_CONCEPT_CHECKS /usr/include/c++/3.4/x86_64-linux-gnu/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ /usr/include/c++/3.4/i486-linux-gnu/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ /usr/include/c++/4.1/bits/concept_check.h:#ifndef _GLIBCXX_CONCEPT_CHECKS /usr/include/c++/4.1/i486-linux-gnu/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ /usr/include/c++/4.1/i486-linux-gnu/64/bits/c++config.h:/* #undef _GLIBCXX_CONCEPT_CHECKS */ Next, on GCC 4.3.0 source code (edited results - removed .html and ChangeLogs): /root/downloads/gcc-4_3-trunk/libstdc++-v3/include/bits/concept_check.h /root/downloads/gcc-4_3-trunk/libstdc++-v3/src/Makefile.in /root/downloads/gcc-4_3-trunk/libstdc++-v3/src/concept-inst.cc /root/downloads/gcc-4_3-trunk/libstdc++-v3/src/Makefile.am /root/downloads/gcc-4_3-trunk/libstdc++-v3/configure /root/downloads/gcc-4_3-trunk/libstdc++-v3/config.h.in /root/downloads/gcc-4_3-trunk/libstdc++-v3/acinclude.m4 The file gcc-4_3-trunk/libstdc++-v3/docs/html/17_intro/howto.html says: "Undefined by default. Configurable. When defined, performs compile-time checking on certain template instantiations to detect violations of the requirements of the standard." It would be better if they were on by default - I can compile GCC 4.2 and 4.3 on target i686-pc-linux-gnu with them on. It seems unfortunate to have them off. This file obviously needs a little update but, gcc-4_3-trunk/libstdc++-v3/docs/html/19_diagnostics/howto.html says: "They are off by default for all versions of GCC from 3.0 to 3.4 (the latest release at the time of writing). They can be enabled at configure time with "--enable-concept-checks". You can enable them on a per-translation-unit basis with "#define _GLIBCXX_CONCEPT_CHECKS" for GCC 3.4 and higher (or with <code>#define _GLIBCPP_CONCEPT_CHECKS</code> for versions 3.1, 3.2 and 3.3)." Reading that tells me that they are off by default and if you configure GCC using "--enable-concept-checks" they are also automatically on for any code you compile, thus the error message. Suggested FIX: The error message could be converted to a warning message _IF_ the compiler detected the problem and instead of issuing an error message used a (NEW) GCC command line switch "-fno-concept-checks" to disable the checks for the one file - better yet, for the one function (or line of code!). This would give us the benefit of concept checks without the problem of needing to rewrite older code to avoid what is described as "Strange message when operator++ not found". Indeed, if not strange it is a challenge for a non C++ programmer to figure out the line of source code at fault from the resulting error message, A precident for adding a new GCC option ("-fno-concept-checks"), (or allowing "-fpermissive" to en/disable it), is that when reading the gcc.info file, section "C++ Dialect Options", I see that we have options like: -fabi-version=N , -fno-access-control , -fcheck-new , -ffriend-injection , -fno-enforce-eh-specs , -ffor-scope , -fno-optional-diags , -fpermissive , -fuse-cxa-atexit , -fno-use-cxa-get-exception-ptr , -Wabi ... etc. IE: most of the options for C++ _are_ to permit violations of the standards. Having concept check ON by default instead of OFF is better. It would not be impossible to have them enabled and issue a warning instead of a multi-line error message. GCC 4.3.0 uses Boost version 1.12.0, but the newest version is 1.34.0, might be that an upgrade would be a task to add to the job jar.
One comment, to avoid wasting time (I don't have the time to understand why the old library-simulation of concept checks is discussed in a C++ PR): for sure we are not going to enable by default the simulated concept checks (and all the compile-time performace issues and slight non-conformance issues). It's way, way, too late for that. *Real* concepts are finally, gloriously coming in C++0x. We can only consider slightly tweaking what we have in case some of the "concepts" are slightly off. Only a tad above regression-only mode.
Subject: Bug 16696 Author: manu Date: Tue Aug 4 15:51:12 2009 New Revision: 150461 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=150461 Log: 2009-08-04 Manuel López-Ibáñez <manu@gcc.gnu.org> PR c++/16696 cp/ * call.c (build_new_op): Only try prefix operator if -fpermissive, otherwise just error. testsuite/ * g++.dg/parse/pr16696.C: New. * g++.dg/parse/pr16696-permissive.C: New. Added: trunk/gcc/testsuite/g++.dg/parse/pr16696-permissive.C trunk/gcc/testsuite/g++.dg/parse/pr16696.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/testsuite/ChangeLog
FIXED in GCC 4.5.