Sign in to follow this  

Is there any way to do this

This topic is 4307 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Huh!! It was not a home work...It just couldn't catch up with people's reply...otherwise I would have explained the problem if anybody would have asked for it. anyways here's my question again How can I change the code int main() { std::cout<<"Hello World!\n"; return 0; } to produce this output: Initialize Hello World! Clean Up Do not change main() in any way. What I thought was(I didn't saw anyone's reply)....if I do this #include <iostream.h> class my1 { public: my1(){cout<<"Initialize\n";} ~my1(){cout<<"Clean Up\n";} }; class my2 { public: static my1 a; }; my1 my2::a; //definition of static onject, thus space will be allocate and constructor will be called int main() { std::cout<<"Hello World!\n"; return 0; //at exit, static object destructor will be called. } But output was only Initialize Hello World! Is there any way that clean up should also be outputted

Share this post


Link to post
Share on other sites
It works on my machine. (BTW, #include <iostream>, not <iostream.h>)

Maybe it's a problem with buffered output? Try cout << "Clean Up" << std::endl;, that should flush the buffer immediately, or use cerr maybe.

EDIT: Just for kicks, this is how your teacher whoever made the exercise would not want it solved:


#include <iostream>

using std::cout;
#define std cout<<"Initialize!\n";std
#define return cout<<"Clean Up!\n";return 0;

int main()
{
std::cout<<"Hello World!\n";
return 0;
}



EDIT2: Or this!


#include <iostream>

int main()
{
std::cout << "Initialize!\nHello World!\nClean Up!\n";
}

#define main this_is_not_main

int main()
{
std::cout<<"Hello World!\n";
return 0;
}

Share this post


Link to post
Share on other sites
I don't know enough about namspaces, but perhaps you could somehow block iostream's "std" namespace and create your own class with "std" namespace, and make your own "cout" which passes arguments to the "real cout", and overload "<<". Just another idea.


discman1028

Share this post


Link to post
Share on other sites
Quote:
Original post by load_bitmap_file
It works on my machine. (BTW, #include <iostream>, not <iostream.h>)

Maybe it's a problem with buffered output? Try cout << "Clean Up" << std::endl;, that should flush the buffer immediately, or use cerr maybe.


I tried on VC6.0 and DEV C++(latest version)...it didn't work.

I tried what you suggested...but still it's not working.

Share this post


Link to post
Share on other sites
This works just fine...


struct SDummy
{
SDummy(void)
{
std::cout << "Foo" << std::endl;
}

~SDummy(void)
{
std::cout << "Bar" << std::endl;
}
};

SDummy g_pDummy;

void main(void)
{
std::cout << "Test" << std::endl;
}




Share this post


Link to post
Share on other sites
I would move the "my1 my2::a;" line inside of main(), rather than outside...

Because you are making a static declaration, the constructor and destructor function pointers are being simply added to the ctor and dtor lists. It is possible that whatever library implementation you are using might have its dtor called before yours, shutting down the library before it can output your text.

Edit: Then I re-read the post and see "Do not change main() in any way." *sigh* Oh well, I tried :)

Share this post


Link to post
Share on other sites
#include <iostream>

std::ostream & operator<<(std::ostream & stream, char const * const data)
{
return std::operator<<(std::operator<<(std::operator<<(stream, "Initialize\n"), data), "Clean Up\n");
}

int main()
{
std::cout << "Hello World!\n";
return 0;
}
or
#include <iostream>

namespace my
{
int main()
{
std::cout << "Hello World!\n";
return 0;
}
}

int main()
{
std::cout << "Initialize\n";
int r = my::main();
std::cout << "Clean Up\n";
return r;
}
Σnigma

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Quote:
Original post by bpoint
If you're just interested in hijacking main, why bother with #defines and namespaces when you can just change the entrypoint? :)


Nice idea, you can do something like this:


#pragma comment(linker, "/entry:Dummy")

int main(void)
{
std::cout << "Hello World!" << std::endl;

return NULL;
}

void Dummy(void)
{
std::cout << "Foo" << std::endl;

main();

std::cout << "Bar" << std::endl;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
Quote:
Original post by bpoint
If you're just interested in hijacking main, why bother with #defines and namespaces when you can just change the entrypoint? :)


Nice idea, you can do something like this:

*** Source Snippet Removed ***


It crashes in VC6.0

Share this post


Link to post
Share on other sites
Quote:
Original post by TEUTON
It crashes in VC6.0

That source by itself probably would. None of the ctors are being called, which means libc and stdio file streams aren't even being initialized.

You'll have to call the ctor function table manually first.

Edit: Okay, I had a few minutes over lunch to whip up some code to do it right. This code works on VC6, 2003 and 2005. VC6's libc startup is different than 2003/2005, hence the changed initialization path. It also seems that VC2005's std::cout does not have any dependance on libc initialization, so the last post by raz0r does actually work.

Anyway, here's the code. It's not pretty. :)
#include <iostream>

#define _CRTALLOC(x)

typedef void (__cdecl *_PVFV)(void);

extern "C" {
// pointers to initialization sections
extern _CRTALLOC(".CRT$XIA") _PVFV __xi_a[];
extern _CRTALLOC(".CRT$XIZ") _PVFV __xi_z[];// C initializers
extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[];
extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[];// C++ initializers

extern int _heap_init(int);
extern void _ioinit(void);
extern void _cinit(void);

// taken from internal.h
extern void __cdecl _initterm(_PVFV *, _PVFV *);
extern void _RTC_Initialize(void);
};

#pragma comment(linker, "/entry:entrypoint")

int main()
{
std::cout<<"Hello World!\n";
return 0;
}

void initialize()
{
#if _MSC_VER < 1300
// initialize heap
_heap_init(0);

// initialize lowio
_ioinit();

// do C data initialize
_cinit();
#else
// initialize runtime C library
_RTC_Initialize();

// call C/C++ initializers
_initterm(__xi_a, __xi_z);
_initterm(__xc_a, __xc_z);
#endif
}

void entrypoint()
{
initialize();

std::cout<<"Initialize\n";

main();

std::cout<<"Clean Up\n";
}


Note that dtors aren't called, and the onexit/atexit table is not even initialized. If you want full functionally, feel free to implement them. :)


[Edited by - bpoint on March 1, 2006 10:10:11 PM]

Share this post


Link to post
Share on other sites

This topic is 4307 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this