ISO C++ forbids declaration of "tst" with no type

  • Thread starter Henrik S. Hansen
  • Start date
H

Henrik S. Hansen

I'm new to C++, and cannot figure out why this won't compile:

std::map<std::string, int> tst;
tst["a"] = 1;

int main() { /*...*/ }

It gives me:
error: ISO C++ forbids declaration of `tst' with no type

However, if I do:

int main() {
std::map<std::string, int> tst;
tst["a"] = 1;
}

It works. Why is that? I cannot find the (reasonable, I suspect)
explanation in Stroustup's TC++PL.
 
J

Jack Applin

Henrik S. Hansen said:
I'm new to C++, and cannot figure out why this won't compile:

std::map<std::string, int> tst;
tst["a"] = 1;

int main() { /*...*/ }

You can't have an assignment outside of a function.
This would produce a similar error:

int foo;
foo = 1;

int main() { /*...*/ }

The compiler thinks that it's a declaration, with an initial value:

int foo = 1;

but the type (int, in this case) is missing.
 
A

Alf P. Steinbach

* (e-mail address removed) (Henrik S. Hansen) schriebt:
I'm new to C++, and cannot figure out why this won't compile:

std::map<std::string, int> tst;
tst["a"] = 1;

int main() { /*...*/ }

It gives me:
error: ISO C++ forbids declaration of `tst' with no type

However, if I do:

int main() {
std::map<std::string, int> tst;
tst["a"] = 1;
}

It works. Why is that? I cannot find the (reasonable, I suspect)
explanation in Stroustup's TC++PL.

I don't know whether it's reasonable or not -- at first sight it seems
very reasonable, then as one thinks about it it seems less reasonable.

The basics: in C++ you cannot put executable statements directly at
namespace scope, that is, outside a function body.

So you have to put them in e.g. 'main'.

That seems reasonable; after all, in what order should statements at
namespace scope be executed in a multi-file program?

But then, you can achieve nearly the same effect simply by declaring dummy
variables and initialize them by function calls, e.g.


int dummy001 = myDummyFunction001( argument1, argument2, argument3 );
int dummy002 = myDummyFunction002( argument1, argument2, argument3 );
int dummy003 = myDummyFunction003( argument1, argument2, argument3 );


Now in what order should those functions be called?

Within a compilation unit this is well-defined: it's the order of declaration.

Across compilation units it's messy, messy, messy. You're not even guaranteed
that they are actually called, unless some other part of the program calls
some function in the relevant compilation unit. And if one of those functions
throws an exception you're not even guaranteed that 'main' will be called.

At that point in the reasoning it begins to seem reasonable again to have all
calls, all that actually is done, originating in 'main'.

But then one can reason further and think about e.g. initialization of the
standard i/o-streams.

And then one discovers that hey, here's something lacking in the language:
those streams are initialized (at namespace scope) by some mechanism that _is
not_ available to you, the C++ "end user".

So there's something not quite solved here. It's much like reasoning about
relativity theory. As a child you find it obviously wrong, then as a teenager
obviously correct, then maturing a bit you find some less than well-defined
parts, then those parts, after a while, again seem reasonable, and so on, but
the upshot is that there is a little gray terra incognita where there is still
something to be discovered, and all the difficulties emanate from that area.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top