Bug 16696 - Strange message when operator++ not found
Summary: Strange message when operator++ not found
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.0.0
: P2 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks: 16992
  Show dependency treegraph
 
Reported: 2004-07-23 20:39 UTC by Wolfgang Bangerth
Modified: 2009-08-04 15:52 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2006-02-26 19:29:54


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wolfgang Bangerth 2004-07-23 20:39:46 UTC
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.
Comment 1 Andrew Pinski 2004-07-23 20:58:37 UTC
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.
Comment 2 Wolfgang Bangerth 2004-07-23 21:02:27 UTC
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/

Comment 3 Andrew Pinski 2004-07-23 21:08:22 UTC
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).
Comment 4 Wolfgang Bangerth 2004-07-23 21:12:36 UTC
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/

Comment 5 Andrew Pinski 2004-07-23 21:14:26 UTC
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.
Comment 6 Wolfgang Bangerth 2004-07-23 21:19:00 UTC
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/

Comment 7 Andreas Schwab 2004-07-23 21:41:35 UTC
Pre-1985 C++ didn't distinguish between prefix and postfix ++ and operator++() 
was used for both. 
Comment 8 Wolfgang Bangerth 2004-07-23 23:27:53 UTC
Subject: Re:  Strange message when operator++ not found


> Pre-1985 C++

:-)) I thought I was old already, but apparently not old enough...
W.

Comment 9 Rob 2007-07-06 08:13:11 UTC
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
Comment 10 Rob 2007-07-07 18:05:56 UTC
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.
Comment 11 Paolo Carlini 2007-07-07 18:27:15 UTC
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.
Comment 12 Manuel López-Ibáñez 2009-08-04 15:51:32 UTC
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

Comment 13 Manuel López-Ibáñez 2009-08-04 15:52:41 UTC
FIXED in GCC 4.5.