Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
234 views
in Technique[技术] by (71.8m points)

c++ - Why statements cannot appear at namespace scope?

Any idea on which rule in standard states the statements like this:

p++; //where 'p' is pointer to array

cannot appear in global scope?

I'm looking for a reference not just an explanation if possible.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...