Why statements cannot appear at namespace scope?

本秂侑毒 提交于 2019-11-28 01:36:17
Nawaz

The expression p++ which you've written is at namespace scope. It is forbidden by the grammer of namespace-body which is defined in §7.3.1/1 as:

namespace-body:
     declaration-seqopt

which says the namespace-body can optionally contain only declaration. And p++ is surely not a declaration, it is an expression, therefore the Standard implicitly forbids it. The Standard might have explicit statement forbidding this, but I think the above should be enough.

In the same way, you cannot do this:

namespace sample
{
  f(10,10); //error
  std::cout << "hello world" << std::endl;//error
}

But if you somewhow convert expressions into declarations (or rather use expressions in declarations), then you could evaluate the so-called expressions. Here is one trick:

#include<iostream>

namespace sample
{
  struct any { template<typename T> any(const T&){} };

  void f(int a,int b) { std::cout << a * b <<  std::endl; }

  any a1= (f(10,10), 0); //ok
  any a2 = std::cout << "hello world" << std::endl;//ok
}

int main() {}

Output (if you're lucky):

100
hello world

Online demo : http://ideone.com/icbhh

Notice that the return type of f() is void, which means I cannot write the following (see error):

any a1 = f(10,10); //error

That is why I used comma operator so that the expression could have some value, which evaluates to the last operand in the comma expression. In case of std:cout, since it returns std::ostream&, I don't need to use comma operator; it is fine without it.

One more interesting thing in the above code: why I defined any and a templated constructor in it? The answer is, I wrote this so that I could assign value of any type (no pun intended), be it int, std::ostream& or whatever. The templated constructor can take argument of any type.

But don't write such code. They're not guaranteed to work the way you expect.

Read the answers in this topic where you would see why such coding could be dangerous:

By saying "statements like this" I guess you know that/why statements in general cannot be in global scope.

p++;

Is a statement because it basically is translated into:

p = p + 1;

Which is a normal statement.

CHeck out "The C++ programming Language" by of course Stroustrup.

Section r.6.1 talks about statements - which can be labels, expressions, compound statements, selection statements, iteration statements, jump statements or declaration statements.

Then jump back to section 3.3.1 Which shows the statement syntax and references: Note that.....there is no assignment statement or procedure call statement. Assignment and function call are handled as expressions.

Section r.3.1 then talks about four types of scope - local, function, file and class. Since global is essentially "file" scope. Names are allowed in global scope as are classes first declared in a return or argument type.

Really could find no concrete definitive that flat out states you can't have an expression statement in global scope, but by omission the references show what you CAN have.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!