Code not working?

This is a discussion on Code not working? within the C++ Programming forums, part of the General Programming Boards category; Does this code compile for anyone else (Visual C++ AND other compilers)? Code: #include <iostream> #include <algorithm> #include <vector> #include ...

  1. #1
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,918

    Code not working?

    Does this code compile for anyone else (Visual C++ AND other compilers)?
    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    
    int main()
    {
    	std::cout << "Enter numbers: ";
    	std::vector<int> MyIntegers( std::istream_iterator<int>(std::cin), std::istream_iterator<int>() );
    	std::cout << "You entered the following numbers: ";
    	std::copy(MyIntegers.begin(), MyIntegers.end(), std::ostream_iterator<int>(std::cout, " "));
    	std::cout << "\n";
    }
    It does NOT compile for me with Visual C++, but it DOES compile with g++ (or gcc, or whatever C::B uses).
    Is this a fabled compiler bug or just a project / machine bug?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    It does not compile on the Comeau online compiler, but the error messages hinted that the declaration of MyIntegers was being interpreted as a function declaration. I used the time honoured extra parentheses trick and Comeau was silenced.

    EDIT:
    Right, I tested on MSVC8, and the compiler actually gave an even better error message than the Comeau online compiler: "(9) : error C2751: 'std::cin' : the name of a function parameter cannot be qualified" versus "line 9: error: qualified name is not allowed". Again, enclosing the std::istream_iterator<int>(std::cin) with an extra set of parentheses silenced the errors.
    Last edited by laserlight; 04-05-2009 at 01:28 PM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,918
    Oh.
    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    
    int main()
    {
    	std::cout << "Enter numbers: ";
    	std::vector<int> MyIntegers( (std::istream_iterator<int>(std::cin)), (std::istream_iterator<int>()) );
    	std::cout << "You entered the following numbers: ";
    	std::copy(MyIntegers.begin(), MyIntegers.end(), std::ostream_iterator<int>(std::cout, " "));
    	std::cout << "\n";
    }
    This seems to work. But why would it be interpreted as a function declaration?
    Clearly, std::istream_iterator<int>() should make it clear that it should call the constructor of such an object, and that it's not a type?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    Quote Originally Posted by Elysia
    Clearly, std::istream_iterator<int>() should make it clear that it should call the constructor of such an object, and that it's not a type?
    hmm... maybe the compiler interpreted that as the declaration of a function that takes no arguments and returns a std::istream_iterator<int>. Consider:
    Code:
    #include <string>
    
    std::string bar();
    
    int main()
    {
        std::string::size_type foo(std::string());
        foo(bar);
    }
    
    std::string::size_type foo(std::string f())
    {
        return f().length();
    }
    
    std::string bar()
    {
        return "Hello world!";
    }
    Last edited by laserlight; 04-05-2009 at 01:38 PM. Reason: Even better example involving std::string.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,918
    My only conclusion is that The VC++ compiler becomes utterly confused and thinks that std::cin is the name of a parameter, which doesn't make make much sense since it isn't the syntax of any declaration of sorts. In that case, the compiler should probably have complained about syntax error...

    Very confusing. Still, I would consider this a bug in the compiler, then?
    C++ really needs to make a clearer distinction between different things, methinks. Especially, declarations and initialization.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    Quote Originally Posted by Elysia
    My only conclusion is that The VC++ compiler becomes utterly confused and thinks that std::cin is the name of a parameter, which doesn't make make much sense since it isn't the syntax of any declaration of sorts. In that case, the compiler should probably have complained about syntax error...
    MSVC did complain about a syntax error: "error C2751: 'std::cin' : the name of a function parameter cannot be qualified". It does seem reasonable to consider that the programmer might be trying to use std::cin as the name of a parameter. The reason is shown in my example in post #4. We could modify it:
    Code:
    #include <string>
    
    typedef int cin;
    
    std::string bar();
    
    int main()
    {
        std::string::size_type foo(std::string(), cin);
        foo(bar, 0);
    }
    
    std::string::size_type foo(std::string f(), cin n)
    {
        return f().length() + n;
    }
    
    std::string bar()
    {
        return "Hello world!";
    }
    Quote Originally Posted by Elysia
    Very confusing. Still, I would consider this a bug in the compiler, then?
    Yes, I think it is a bug in g++ 3.4.5.

    Quote Originally Posted by Elysia
    C++ really needs to make a clearer distinction between different things, methinks. Especially, declarations and initialization.
    I agree. I believe that this syntax is actually inherited from C, but in C++ it becomes particularly confusing.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User carrotcake1029's Avatar
    Join Date
    Apr 2008
    Posts
    398
    MinGW on Windows Vista [gcc version 3.4.5 (mingw-vista special r3)] has no errors/warnings when compiled as
    Code:
    g++ test.cpp -Wall -pedantic
    Seems your conclusion is correct.

  8. #8
    The larch
    Join Date
    May 2006
    Posts
    3,573
    Well, a function definition might look like this (if I'm not mistaken and the extra brackets are allowed):

    Code:
    int foo(int(n), int(m));
    Compare this with you vector declaration.

    It seems that the only thing that makes GCC realize it's not a function definition is the appearance of std::cin. Replace that with any other user-defined stream and it will give a compiler error too:

    Code:
    std::istream& my_cin = std::cin;
    std::cout << "Enter numbers: ";
    std::vector<int> MyIntegers( std::istream_iterator<int>(my_cin), std::istream_iterator<int>() );
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    Quote Originally Posted by anon
    Well, a function definition might look like this (if I'm not mistaken and the extra brackets are allowed):
    As I have shown, they are not just extra brackets/parentheses, but change the meaning of the parameter declarations to be function types.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I meant you can put the argument name in extra brackets, and it is still just argument name.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    Quote Originally Posted by anon
    I meant you can put the argument name in extra brackets, and it is still just argument name.
    Ah yes, that is also true.

    Quote Originally Posted by anon
    It seems that the only thing that makes GCC realize it's not a function definition is the appearance of std::cin.
    By the way, you actually mean to say function declaration rather than function definition. So, you think that g++ is correct not to report an error because it can tell that the declaration is not a function declaration? That would seem to contradict your next point...

    Quote Originally Posted by anon
    Replace that with any other user-defined stream and it will give a compiler error too:
    The point is that g++ is not reporting an error.
    Last edited by laserlight; 04-06-2009 at 02:13 AM.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    The larch
    Join Date
    May 2006
    Posts
    3,573
    It's hard to tell what the standard is. In function prototypes the compiler should be allowed to ignore the argument names. However, in this case, before ignoring it, GCC looks what it is and sees it's in a namespace - std::cin, therefore it can't be an argument name and the whole vector instance declaration doesn't make sense as a function declaration. With the using declaration it errors as it should:

    Code:
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <iterator>
    
    using std::cin;
    
    int main()
    {
    	std::cout << "Enter numbers: ";
    	std::vector<int> MyIntegers( std::istream_iterator<int>(cin), std::istream_iterator<int>() );
    	std::cout << "You entered the following numbers: ";
    	std::copy(MyIntegers.begin(), MyIntegers.end(), std::ostream_iterator<int>(std::cout, " "));
    	std::cout << "\n";
    }
    One more reason to use using declarations?
    Last edited by anon; 04-06-2009 at 02:46 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,174
    Quote Originally Posted by anon
    However, in this case, before ignoring it, GCC looks what it is and sees it's in a namespace - std::cin, therefore it can't be an argument name.
    The Comeau online compiler and MSVC also checks that part. The difference is that while g++ then interprets the statement as an object definition, the other two immediately interpret it as an error.

    Quote Originally Posted by anon
    One more reason to use using declarations?
    Maybe not: without the line with std::copy(), the result would then still be unexpected, though the compilers would not complain.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. problem with previously working internet code
    By abachler in forum Windows Programming
    Replies: 11
    Last Post: 04-10-2009, 05:11 AM
  2. Replies: 3
    Last Post: 02-24-2009, 08:49 PM
  3. C code not working
    By D3ciph3r in forum C Programming
    Replies: 2
    Last Post: 05-27-2005, 05:13 PM
  4. Trying to eject D drive using code, but not working... :(
    By snowfrog in forum C++ Programming
    Replies: 3
    Last Post: 05-07-2005, 08:47 PM
  5. Linked List Working Code
    By Linette in forum C++ Programming
    Replies: 9
    Last Post: 01-24-2002, 12:00 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21