Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > namespaces and main()

Reply
Thread Tools

namespaces and main()

 
 
poiuz24
Guest
Posts: n/a
 
      07-22-2004
got it: one must suppress C++ name mangling at the
place of definition. this one compiles _and_ links:

foo.cpp = """
namespace foo
{
extern "C" {
int main ()
{
return 0;
}
}
}

using namespace foo;
"""
 
Reply With Quote
 
 
 
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      07-22-2004
poiuz24 wrote:
>
> > You're correct in thinking that:
> >
> > int foo::main();
> >
> > becomes:
> >
> > int ::main();
> >
> >
> > after the line
> >
> > using namespace foo;
> >
> >
> > The only problem is that this only applies to the current
> > translation unit. So when the linker is introduced to the

>
> i don't get it: there is only _one_ translation unit
> involved: foo.cpp


Your program (the source code you wrote) is not the only thing
that is running when your program starts up.

main() is just a function which gets called from the startup
code right after the executable starts. And that startup code
expects main() to be in the global namespace.

If you put main() into a namespace, then this startup code
would need to be recompiled to accomodate for that. But
this is not going to happen. The startup code is fixed.
Just if you wonder 'what does this startup code do?'. Well,
it initiliazes eg. the memory management, setups the standard
input output streams (stdin, stdout), things like that. In short
it initializes the environment your program can expect. Only
after that setup is completed it calles main() in the global
namespace.

--
Karl Heinz Buchegger
http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
tom_usenet
Guest
Posts: n/a
 
      07-22-2004
On 21 Jul 2004 23:57:55 -0700, (E-Mail Removed) (poiuz24) wrote:

>got it: one must suppress C++ name mangling at the
>place of definition. this one compiles _and_ links:
>
>foo.cpp = """
>namespace foo
>{
> extern "C" {
> int main ()
> {
> return 0;
> }
> }
>}
>
>using namespace foo;
>"""


You don't need the "using namespace foo" bit. But the code has
undefined behaviour, since the standard says that the linkage of main
is implementation defined, so the extern "C" bit might or might not
work, since it might be expecting a mangled name.

But why would you want to do this anyway? You're not allowed to call
main yourself.

Tom
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-22-2004
"poiuz24" <(E-Mail Removed)> wrote...
> > Each program shall contain a _global_ 'main' function. Your function
> > is not global, it's inside a namespace. "using" is for your code, not
> > the library code. When you say "using namespace foo", you do not cause
> > recompilation of the library code that would suddenly resolve your

>
> but i don't have no library: above is all in _one_ file. thus, the
> program == one translation unit == one file
>
> i thought the using stmt would introduce ::foo::main into ::
> since the using stmt is in ::
>
> ???


It does introduce it into the global scope, but only for calls by _your_
code. _Your_ code does not call 'main' (nor is it allowed to). For the
rest of the system (whether you call it "library" or not), the function
is still foo::main.

I am not sure what your agenda is, but according to the Standard your
program doesn't have the required _global_ 'main' function. Bringing
the name 'main' declared inside a namespace into the global scope does
not make the function global.

V


 
Reply With Quote
 
JKop
Guest
Posts: n/a
 
      07-22-2004
poiuz24 posted:

> got it: one must suppress C++ name mangling at the
> place of definition. this one compiles _and_ links:
>
> foo.cpp = """
> namespace foo
> {
> extern "C" {
> int main ()
> {
> return 0;
> }
> }
> }
>
> using namespace foo;
> """


That's a hack.

The function's name is:

int foo::main();

When using extern "C", it gets introduced to the linker as:

int main();

The scope thingie is lost, simply because C-linked functions can't have a
namespace.

Anyway, putting main() in a namespace is stupid.


-JKop
 
Reply With Quote
 
poiuz24
Guest
Posts: n/a
 
      07-22-2004
tom_usenet <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>. ..
> On 21 Jul 2004 23:57:55 -0700, (E-Mail Removed) (poiuz24) wrote:
>
> >got it: one must suppress C++ name mangling at the
> >place of definition. this one compiles _and_ links:
> >
> >foo.cpp = """
> >namespace foo
> >{
> > extern "C" {
> > int main ()
> > {
> > return 0;
> > }
> > }
> >}
> >
> >using namespace foo;
> >"""

>
> You don't need the "using namespace foo" bit. But the code has
> undefined behaviour, since the standard says that the linkage of main
> is implementation defined, so the extern "C" bit might or might not


ah, ok. i silently assumed that ::main would be plainly required to
have C linkage by the standard. so many implementation defined
behaviours. whine.

> work, since it might be expecting a mangled name.
>
> But why would you want to do this anyway? You're not allowed to call
> main yourself.


logical program structure. I contemplated over having a logical structure
roughly like this:


#include <iostream>

namespace megacorp
{
namespace projectx
{
namespace modules
{
namespace mylib
{
void foo () { std::cout << "foo ()" << std::endl; }
}
namespace mylib2
{
void foo2 () { std::cout << "foo2 ()" << std::endl; }
}
}
namespace apps
{
namespace myapp1
{
using namespace modules::mylib;
int main () { foo (); return 0; };
}
namespace myapp2
{
using namespace modules::mylib2;
int main () { foo2 (); return 0; };
}
}
}
}


to build one of the apps, i'd just do

#include "stuff"
using namespace megacorp:rojectx::apps::myapp1;

or

#include "stuff"
using namespace megacorp:rojectx::apps::myapp2;

to build the libs, i do:

#include "stuff"
using namespace megacorp:rojectx::libs::mylib;

well, ok. I can plainly forward

#include "stuff"

int main ()
{
return megacorp:rojectx::apps:myapp1::main ();
}


but for some obscure reasons, I first tried the former version,
found that it didn't work and then wanted to learn why.
it's tolarable to have the second version

another background was this: i do lot of templated stuff which
needs to be included with definitions anyway (when export is not
there ..). so i thought maybe i can rid of those nasty header
files altogether. i hate header files. why write code twice? problem
of course with above example is that namespace scoped non-templated
functions may only be defined once (the obnoxious "One Definition Rule").

this one i don't understand either: with namespace scoped templated
functions, having multiple (of course identical) definitions is
_separate_ translation units is allowed by the standard as far as
I know and no problem for the linker to sort out. same goes for const
vars, structs, classes, typedef, ... but NOT plain functions. why?

IOW: how do i get rid of headers

sideconditions:
i dont care a lot on compilation speed .. i don't develop
million line programs .. i just go buy more Ghz

i also dont care about "users" seeing ugly definitions instead
of a "pure" interface in separate headers. users should consult
the (doxygen generated) docs anyway .. not look at code.

in java, nobody complaints ..


>
> Tom

 
Reply With Quote
 
poiuz24
Guest
Posts: n/a
 
      07-22-2004
> Your program (the source code you wrote) is not the only thing
> that is running when your program starts up.


i suppose at least the OS kernel will run
seriously, that one i was aware of ..

>
> main() is just a function which gets called from the startup
> code right after the executable starts. And that startup code
> expects main() to be in the global namespace.
>
> If you put main() into a namespace, then this startup code


i drag it into ::

> would need to be recompiled to accomodate for that. But
> this is not going to happen. The startup code is fixed.
> Just if you wonder 'what does this startup code do?'. Well,
> it initiliazes eg. the memory management, setups the standard
> input output streams (stdin, stdout), things like that. In short
> it initializes the environment your program can expect. Only
> after that setup is completed it calles main() in the global
> namespace.


from tom_usenet's posting I learned: the real point seems to be that
the C++ standard does not specify the linkage conventions for ::main ()

if i force C linkage for my ::main dragged in from foo::main
that _might_ work or not. its plainly undefined behaviour;(

thx for posting anyway
 
Reply With Quote
 
tom_usenet
Guest
Posts: n/a
 
      07-22-2004
On 22 Jul 2004 08:52:25 -0700, (E-Mail Removed) (poiuz24) wrote:

>well, ok. I can plainly forward
>
>#include "stuff"
>
>int main ()
>{
> return megacorp:rojectx::apps:myapp1::main ();
>}


Yup, that's the best way to do it.

>but for some obscure reasons, I first tried the former version,
>found that it didn't work and then wanted to learn why.
>it's tolarable to have the second version
>
>another background was this: i do lot of templated stuff which
>needs to be included with definitions anyway (when export is not
>there ..). so i thought maybe i can rid of those nasty header
>files altogether. i hate header files. why write code twice?


You're not writing code twice, just declarations. The separation is
quite important in very large projects, since .h files should rarely
be modified.

problem
>of course with above example is that namespace scoped non-templated
>functions may only be defined once (the obnoxious "One Definition Rule").


Not true if any of the following is true:
a) They are defined inside a class body.
b) They are declared inline.
c) They are in an anonymous namespace.
d) They are declared static.

>this one i don't understand either: with namespace scoped templated
>functions, having multiple (of course identical) definitions is
>_separate_ translation units is allowed by the standard as far as
>I know and no problem for the linker to sort out.


Actually it's quite a big problem for the linker to sort out - some
linkers can't do it (including one I have used on QNX - .exes ended up
containing multiple definitions of template functions, causing
horrendous bloat). Some compilers have complicated prelinkers that get
around this problem, by assigning each template instantiation to a
particular translation unit, but this requires multiple compilation
passes to find out all the required instantiations. This is what
Comeau C++ does by default.

If you have multiple definitions of a function, either the
compiler/linker has to compile them all, assume they are the same and
discard all but one, or it has to assign the definition to a single
translation unit and not compile it in any of the others. You can
imagine the number of passes that would require!

One way around the bloat issue is just to have a single compilation
unit for your whole program! This might suit you.

> same goes for const
>vars, structs, classes, typedef, ... but NOT plain functions. why?


const vars have static linkage, so you haven't got multiple
definitions, rather each translation unit gets a separate copy. For
static functions this will obviously lead to major code bloat.

>IOW: how do i get rid of headers


Well, I suggested some ways above, but none of them are recommended
since they all lead to bloated executables - the linker knows to merge
different instantations of template functions, but not normal ones.

>sideconditions:
>i dont care a lot on compilation speed .. i don't develop
>million line programs .. i just go buy more Ghz


It's not just compilation speed. It's the fact that any change at all
means you have to recompile absolutely everything.

>i also dont care about "users" seeing ugly definitions instead
>of a "pure" interface in separate headers. users should consult
>the (doxygen generated) docs anyway .. not look at code.


Yes, I don't strongly disagree with that, but the biggest problem is
the dependency bottleneck. You will have major problems with circular
dependencies if you're not careful.

>in java, nobody complaints ..


Actually, they do. Look up posts by James Kanze on the subject, for
one.

It's best not to fight the language - in Java do what it wants, in C++
do what it wants.

Tom
 
Reply With Quote
 
tom_usenet
Guest
Posts: n/a
 
      07-22-2004
On 22 Jul 2004 09:00:03 -0700, (E-Mail Removed) (poiuz24) wrote:

>from tom_usenet's posting I learned: the real point seems to be that
>the C++ standard does not specify the linkage conventions for ::main ()
>
>if i force C linkage for my ::main dragged in from foo::main
>that _might_ work or not. its plainly undefined behaviour;(
>
>thx for posting anyway


You still seem to misunderstand what a using declaration does - it
*doesn't* modify the linkage of the original function in any way. e.g.

namespace foo
{
void f();
}

using foo::f;
//linker still expects foo::f, it's just that code below this point
//looks up f to be foo::f.

e.g. putting a using declaration at the end of a .cpp file (as you
were) has no effect whatsoever.

Tom
 
Reply With Quote
 
Karl Heinz Buchegger
Guest
Posts: n/a
 
      07-23-2004
poiuz24 wrote:
>
> > Your program (the source code you wrote) is not the only thing
> > that is running when your program starts up.

>
> i suppose at least the OS kernel will run
> seriously, that one i was aware of ..


I worded it badly.
What I tried to say is:

The code in main() is not the first code that gets executed
when your program starts. It is not that your operating system,
ehen starting up a program does:
search for main()
start execution at main()

main() is the first function (global objects initialzation
put aside) that gets executed *that is provided by the programmer*

The real thing is more like this:

int start_program()
{
get_argument_list_from_command_line();
set_up_stream_system();
initialize_memory_manager();
...

return main( argc, argv );
}

This code is provided by the system library that is linked
with your executable. So there really is no other choice then
having main() in the global namespace. And since this code
is already precompiled, you cannot use some using directives to
inject main() from some namespace into the global one. For this
to take effect, the above startup code would need to be recompiled
with your using directive in sight. But this is not going to happen.

>
> from tom_usenet's posting I learned: the real point seems to be that
> the C++ standard does not specify the linkage conventions for ::main ()


The C++ standard doesn't specify *any* linkage conventions.
Linkage conventions are outside the scope of the C++ standard as
is the whole process of linkage.

The real point is: You have to play by the rules. You might get
away by violating the rules on some systems but don't have a
guarantee for anything. Your next compiler release might force
main() to have the usual C++ decorated names in the object file.

--
Karl Heinz Buchegger
(E-Mail Removed)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
.NET 2.0 and namespaces in web apps Amil ASP .Net 2 03-14-2006 09:28 PM
Namespaces in Vs2005 and ASP.net 2.0 Tariq ASP .Net 1 11-29-2005 07:14 PM
Namespaces and Naming conventions Floppy Jellopy ASP .Net 4 07-21-2005 01:36 PM
@Import Syntax and Importing Namespaces in global.asax file D. Shane Fowlkes ASP .Net 1 01-13-2004 02:55 PM
JSTL, XML and namespaces Digby Java 0 10-29-2003 07:54 AM



Advertisments