8
#include<iostream>
using namespace std;
int main(){
     cout<"Yes"; 
}

it compiles, but when it runs, it does nothing. this is a compilation error elsewhere. compiler is gcc 4.9.2

compared with

 #include<iostream>
    using namespace std;
    int main(){
         cout<<"Yes"; 
    }

it has a missing '<' but it still compiles.

I expected it to be a compilation error, as with variables, like this:

> 6 6   C:\Users\Denny\Desktop\Codes\compileerror.cpp   [Error] no match for
> 'operator<' (operand types are 'std::ostream {aka
> std::basic_ostream<char>}' and 'int')

this happens with the code below as well.

   #include<iostream>
    using namespace std;
    int main(){
         cin>"Yes"; 
    }

edit: The same thing happens for

#include<iostream>
int main(){
    
    std::cout<"Yes";
}

plus, I enabled compiler warnings and there are none.

Miao Wang
  • 101
  • 4
  • Did you mean to write `cout << "Yes";`? – πάντα ῥεῖ Nov 03 '21 at 10:19
  • Please provide your code as text in a correctly formatted [mcve]. You should also explain why you think it *shouldn't* compile. – G.M. Nov 03 '21 at 10:20
  • Don't post code as images, copy paste your code directly in the question. – ShadowMitia Nov 03 '21 at 10:22
  • 5
    There are a lot of typos that result in syntactically correct code. – Retired Ninja Nov 03 '21 at 10:24
  • 4
    GCC 4.9.2 is pretty outdated, you might try a newer one – though wondering why there's a less operator for `std::ostream` and pointers (if it compiles, as you say)... – Aconcagua Nov 03 '21 at 10:25
  • Side note: About [`using namespace std`](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)... – Aconcagua Nov 03 '21 at 10:26
  • 5
    Why this question was closed ? Until C++11, basic_ios has `operator void*()` so cout is casted to pointer, then < is used to compare two pointers. – rafix07 Nov 03 '21 at 10:28
  • 2
    I would consider voting to reopen if you posted your text as text, not as links or images. – molbdnilo Nov 03 '21 at 10:30
  • If you enable compile warnings, you should get "expression result unused" or a similar warning. – VLL Nov 03 '21 at 10:32
  • In fact, none of the recent versions of some major compilers does accept your broken code: [Compiler Explorer](https://godbolt.org/z/vPsPfGnGP) (while gcc v4.9.2 accepts both). – Scheff's Cat Nov 03 '21 at 10:56
  • This is now a pretty good question. Nice update. – molbdnilo Nov 03 '21 at 19:44

2 Answers2

10

Default C++ standard in GCC<6.1 (which includes your 4.9.2) is gnu++98, while for GCC≥6.1 it's gnu++14 (as documented e.g. here). Thus the latter compiler won't accept this code by default, due to explicit operator bool() being present in the iostreams since C++11 instead of operator void*() in C++98 (see e.g. cppreference).

You could have been warned if you had turned on the warnings:

$ g++-4.8 test.cpp -o test -Wall
test.cpp: In function ‘int main()’:
test.cpp:5:15: warning: value computed is not used [-Wunused-value]
     std::cout < "Yes";
               ^

where test.cpp contains example code:

#include <iostream>

int main()
{
    std::cout < "Yes";
}
Ruslan
  • 18,162
  • 8
  • 67
  • 136
5

Prior to C++11, the way that if (std::cin >> var) was supported was the stream objects having an implicit conversion to void *.

So std::cout<"Yes" is evaluated as calling the built in bool operator<(void*, const void*), after applying the conversions std::basic_ios -> void * and const char[4] -> const char* -> const void*.

Since C++11, there is now a rule that an explicit conversion to bool can be used in if, while etc. With that, the operator void* was changed to be explicit operator bool, and overload resolution correctly finds no match for std::cout<"Yes"

Caleth
  • 52,200
  • 2
  • 44
  • 75
  • I'd like to add that g++ 4.9.2 accepts this broken code even with `-std=c++11 -pedantic` ([Compiler Explorer](https://godbolt.org/z/Yaa1q49d8)). It's probably simply too old to handle this correctly. – Scheff's Cat Nov 03 '21 at 11:08
  • `void*, char const*` operator? Isn't that `void*, void*` instead? – Aconcagua Nov 03 '21 at 11:34
  • @Scheff'sCat one difference of 4.8 from 5.5 (versions that I have locally) is that the former defines `basic_ios::operator void*()` unconditionally, while the latter defines it only for `__cplusplus < 201103L`. I suppose 4.8 doesn't differ much from 4.9 in this regard. – Ruslan Nov 03 '21 at 13:42