Cout ≪≪ Order of Call to Functions It Prints

cout order of call to functions it prints?

There's no sequence point with the << operator so the compiler is free to evaluate either dequeue function first. What is guaranteed is that the result of the second dequeue call (in the order in which it appears in the expression and not necessarily the order in which it is evaluated) is <<'ed to the result of <<'ing the first (if you get what I'm saying).

So the compiler is free to translate your code into some thing like any of these (pseudo intermediate c++). This isn't intended to be an exhaustive list.

auto tmp2 = myQueue.dequeue();
auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

or

auto tmp1 = myQueue.dequeue();
auto tmp2 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
tmp3 << tmp2;

or

auto tmp1 = myQueue.dequeue();
std::ostream& tmp3 = cout << tmp1;
auto tmp2 = myQueue.dequeue();
tmp3 << tmp2;

Here's what the temporaries correspond to in the original expression.

cout << myQueue.dequeue() << myQueue.dequeue();
| | | | |
| |____ tmp1 _____| |_____ tmp2 ____|
| |
|________ tmp3 _________|

order of function call inside cout

As stated here: https://en.cppreference.com/w/cpp/language/eval_order

Order of evaluation of any part of any expression, including order of
evaluation of function arguments is unspecified (with some exceptions
listed below). The compiler can evaluate operands and other
subexpressions in any order, and may choose another order when the
same expression is evaluated again.

There is no concept of left-to-right or right-to-left evaluation in
C++. This is not to be confused with left-to-right and right-to-left
associativity of operators: the expression a() + b() + c() is parsed
as (a() + b()) + c() due to left-to-right associativity of operator+,
but the function call to c may be evaluated first, last, or between
a() or b() at run time

In your line

cout << sum(3) << sum(2)

the order of the two operator<< calls depends on the operator you use (here << so left-to-right), but the evaluation of each subexpression, namely sum(3) and sum(2) has no defined order and depends on the mood (most optimized compile approach usually) of your compiler.

For info here is a list of operators associativity: https://en.cppreference.com/w/cpp/language/operator_precedence

Called a function with cout statement inside a cout statement

The order of evaluation of arguments to a function is unspecified. Your line looks like this to the compiler:

operator<<(operator<<(operator<<(cout, "The Lucky "), print()), endl);

The primary call in the statement is the one with endl as an argument. It is unspecified whether the second argument, endl, is evaluated first or the larger sub-expression:

operator<<(operator<<(cout, "The Lucky "), print())

And breaking that one down, it is unspecified whether the function print() is called first, or the sub-expression:

operator<<(cout, "The Lucky ")

So, to answer your question:

What causes this behavior? Does this has to do with C++ standard or its behavior vary from one compiler to another?

It could vary from compiler to compiler.

Order of evaluation of arguments using std::cout

The evaluation order of elements in an expression is unspecified (except some very particular cases, such as the && and || operators and the ternary operator, which introduce sequence points); so, it's not guaranteed that test will be evaluated before or after foo(test) (which modifies it).

If your code relies on a particular order of evaluation the simplest method to obtain it is to split your expression in several separated statements.

call function with cout inside a cout statement

This seems to be a very common misunderstanding among beginners. Printing something via cout is not the same as returning a value from a function. Thats completely orthogonal things.

You can write:

std::string returned_value = get_something();
std::cout << returned_value;

But you cannot write:

??? returned_value = print_something();   
std::cout << returned_value;

because print_something() does not return anything! void denotes the absence of a type. You cannot have an object of type void.

On the other hand, when you call a function, you can use the returned value (above), or you can ignore it, so this is correct code:

 print_something();       // prints something
get_something(); // also print something and returned value is ignored

Note that the function get_something should get a better name, because it is not just "getting" a value. How about print_and_return_something()?

PS:

What I am really confused about is that, how is it possible to do a cout after a cout? Am I just missing what cout actually does?

Not sure If I understand, but I will try... std::cout is an object of type std::ostream. It has an operator<< that you can call, similar to calling methods of other objects. The following two are identical and just use different syntax:

std::cout.operator<<( "Hello World");
std::cout << "Hello World";

When you call print_something() then first the function is executed, then the return value is returned to the caller and execution continues with the caller. This:

std::cout << get_something(); 

is more or less the same as (well, its a crude simplification, but should be ok here):

// inside get_something
std::cout << "output something";
// return value
std::string result{"output something"};
// now execution continues in caller
std::cout << result;

Calling cout after cout is no different from calling some other function. Suppose you have a function print() that prints something then you can write

std::string print_and_return() {
std::string x{"Hello World"};
print(x);
return x;
}

The caller can do

std::string x = print_and_return(); // <- this already calls print()
print(x); // now we call it again

This is more or less the same as yours, just that I used some hypothetical print() instead of std::cout::operator<<.

How object cout prints multiple arguments?

IOStreams only take one argument at a time, so it works just fine. :)

The magic of operator overloading means that this:

std::cout << a << b << c;

is actually this:

std::operator<<(std::operator<<(std::operator<<(std::cout, a), b), c);

or this:

std::cout.operator<<(a).operator<<(b).operator<<(c);

(Depending on the types of a, b and c, either a free function or a member function will be invoked.)

and each individual call is to an overload that accepts the type you give it. No argument-counting or format strings required, as they are with your single calls to printf.

How to print function pointers with cout?

There actually is an overload of the << operator that looks something like:

ostream & operator <<( ostream &, const void * );

which does what you expect - outputs in hex. There can be no such standard library overload for function pointers, because there are infinite number of types of them. So the pointer gets converted to another type, which in this case seems to be a bool - I can't offhand remember the rules for this.

Edit: The C++ Standard specifies:

4.12 Boolean conversions

1 An rvalue of arithmetic,
enumeration, pointer, or pointer to
member type can be converted to an
rvalue of type bool.

This is the only conversion specified for function pointers.

Function that prints something to std::ostream and returns std::ostream?

You can't fix the function. Nothing in the spec requires a compiler to evaluate a function call in an expression in any particular order with respect to some unrelated operator in the same expression. So without changing the calling code, you can't make MyPrint() evaluate after std::cout << "Value: "

Left-to-right order is mandated for expressions consisting of multiple consecutive << operators, so that will work. The point of operator<< returning the stream is that when operators are chained, the LHS of each one is supplied by the evaluation of the operator to its left.

You can't achieve the same thing with free function calls because they don't have a LHS. MyPrint() returns an object equal to std::cout, and so does std::cout << "Value: ", so you're effectively doing std::cout << std::cout, which is printing that hex value.

Since the desired output is:

Value: 12

the "right" thing to do is indeed to override operator<<. This frequently means you need to either make it a friend, or do this:

class WhateverItIsYouReallyWantToPrint {
public:
void print(ostream &out) const {
// do whatever
}
};

ostream &operator<<(ostream &out, const WhateverItIsYouReallyWantToPrint &obj) {
obj.print(out);
}

If overriding operator<< for your class isn't appropriate, for example because there are multiple formats that you might want to print, and you want to write a different function for each one, then you should either give up on the idea of operator chaining and just call the function, or else write multiple classes that take your object as a constructor parameter, each with different operator overloads.



Related Topics



Leave a reply



Submit