wu :: forums
« wu :: forums - Change the Output, Don't Change the Code »

Welcome, Guest. Please Login or Register.
May 19th, 2024, 9:32am

RIDDLES SITE WRITE MATH! Home Home Help Help Search Search Members Members Login Login Register Register
   wu :: forums
   riddles
   cs
(Moderators: ThudnBlunder, Eigenray, Grimbal, Icarus, william wu, SMQ, towr)
   Change the Output, Don't Change the Code
« Previous topic | Next topic »
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print
   Author  Topic: Change the Output, Don't Change the Code  (Read 1492 times)
Barukh
Uberpuzzler
*****






   


Gender: male
Posts: 2276
Change the Output, Don't Change the Code  
« on: Mar 25th, 2004, 4:24am »
Quote Quote Modify Modify

Consider the following C++ program which is yet another version of “Hello, world!”.
 
Code:
#include <stdio.h>
 
class A {
//      public: void print(void) { cout << "Hello, world!\n"; };
    public: void print(void) { printf("Hello, world!\n"); };
};
 
main()
{
        A a;
        a.print();
}

 
Change the code so that it prints the line of  ’*’ before and after the “Hello, world!”. The following is forbidden:
 
1. Changing the class A definition code.
2. Changing the main() code.
3. Using #define’s and name spaces.
 

Modified the code
« Last Edit: Mar 25th, 2004, 11:11pm by Barukh » IP Logged
towr
wu::riddles Moderator
Uberpuzzler
*****



Some people are average, some are just mean.

   


Gender: male
Posts: 13730
Re: Change the Output, Don't Change the Code  
« Reply #1 on: Mar 25th, 2004, 5:20am »
Quote Quote Modify Modify

Put the following piece of code in front of it (as is, the original code shouldn't compile anyway)
 
::
#include <stdio.h>
 
class Cout
{
public:
  void operator<< (char * s)
  {
    printf("%s%s%s", "******************** \n",
      s,
      "******************** \n");
  }
};
 
Cout cout;
::
 
« Last Edit: Mar 25th, 2004, 5:26am by towr » IP Logged

Wikipedia, Google, Mathworld, Integer sequence DB
Barukh
Uberpuzzler
*****






   


Gender: male
Posts: 2276
Re: Change the Output, Don't Change the Code  
« Reply #2 on: Mar 25th, 2004, 11:14pm »
Quote Quote Modify Modify

on Mar 25th, 2004, 5:20am, towr wrote:
Put the following piece of code in front of it (as is, the original code shouldn't compile anyway)

Is it because of some #includes missing  Wink? Well, I modified the code. Would you like to give it another try? I mean, something less drastic than overwriting the 'cout'  Grin  
 
Nice try, though...
IP Logged
kellys
Junior Member
**





   


Gender: male
Posts: 78
Re: Change the Output, Don't Change the Code  
« Reply #3 on: Mar 25th, 2004, 11:39pm »
Quote Quote Modify Modify

Well, when you ask people to hack your code, you're going to get a lot of this...
Code:

#include <stdio.h>
 
class A {
// public: void print(void) { cout << "Hello, world!\n"; };
    public: void print(void) { printf("Hello, world!\n"); };
};
 /*
main()
{
   A a;
   a.print();
}  
*/
main() { printf("********\nHello, world!\n*********\n"); }

 
Or, if you won't allow comments, replace /* by #ifdef alsdjfwklejflwekjfe and */ by #endif
« Last Edit: Mar 25th, 2004, 11:58pm by kellys » IP Logged
kellys
Junior Member
**





   


Gender: male
Posts: 78
Re: Change the Output, Don't Change the Code  
« Reply #4 on: Mar 25th, 2004, 11:47pm »
Quote Quote Modify Modify

All right, I'm sorry that was cheap.  Technically, I didn't change your code.
Here's an actual answer,

#include <stdio.h>
 
class B {
 
class A {
    public: void print(void) { printf("Hello, world!\n"); };
};
 
    public: void print(void) { printf("***Hello, world!***\n"); };
};
 
typedef B A;
 
main()
{
  A a;
  a.print();
}  
 

Not quite a line of *s, but you get the idea.  Actually, I guess it's the same thing as my previous post.  So Barukh, what do you mean by 'don't change the definition of A or main'?
« Last Edit: Mar 25th, 2004, 11:51pm by kellys » IP Logged
towr
wu::riddles Moderator
Uberpuzzler
*****



Some people are average, some are just mean.

   


Gender: male
Posts: 13730
Re: Change the Output, Don't Change the Code  
« Reply #5 on: Mar 26th, 2004, 12:36am »
Quote Quote Modify Modify

on Mar 25th, 2004, 11:14pm, Barukh wrote:

Is it because of some #includes missing  Wink?
Well yes, that and the fact cout doesn't exist outside the std namespace.. (So that means I didn't overwrite it either)
 
here's another way, which should, or might, give the same result.. (though Kelly's solution is probably better)
 
::
 
class B {  
    public:  
        B() { printf("*************\n"); }  
        ~B() { printf("*************\n"); }  
};  
 
B b;
 
// b should be constructed before main runs, and thus call printf from the constructor
// after main has run the destructor should be called, and the printf therein should be called
 
::
 
« Last Edit: Mar 26th, 2004, 12:40am by towr » IP Logged

Wikipedia, Google, Mathworld, Integer sequence DB
kellys
Junior Member
**





   


Gender: male
Posts: 78
Re: Change the Output, Don't Change the Code  
« Reply #6 on: Mar 26th, 2004, 12:49am »
Quote Quote Modify Modify

That works towr, and I actually like it better than my answer.
 
I'd like to see more puzzles like this.  There's something pleasurable about hacking code with restrictions.  All of these computer theory puzzles seem so... oh... useful...
IP Logged
towr
wu::riddles Moderator
Uberpuzzler
*****



Some people are average, some are just mean.

   


Gender: male
Posts: 13730
Re: Change the Output, Don't Change the Code  
« Reply #7 on: Mar 26th, 2004, 1:24am »
Quote Quote Modify Modify

Well I believe it works in some compilers, maybe even most. But I'm not sure 'after-program' behavior  (when main has finished, and returned its value to the system) is well-defined. So that's why I have my doubts about my solution..
IP Logged

Wikipedia, Google, Mathworld, Integer sequence DB
Barukh
Uberpuzzler
*****






   


Gender: male
Posts: 2276
Re: Change the Output, Don't Change the Code  
« Reply #8 on: Mar 26th, 2004, 11:18pm »
Quote Quote Modify Modify

on Mar 26th, 2004, 12:49am, kellys wrote:
That works towr, and I actually like it better than my answer.

Me too - towr's solution is what I had in mind.  
 
I have a comment on your soltion: in a sense, you end up with a different code for main (and true, the restrictions are a bit ambigious...)
 
Quote:
I'd like to see more puzzles like this.  There's something pleasurable about hacking code with restrictions.

If so, you will probably like the In Three Ways puzzle.
IP Logged
John_Gaughan
Uberpuzzler
*****



Behold, the power of cheese!

5187759 5187759   john23874   SnowmanJTG
WWW Email

Gender: male
Posts: 767
Re: Change the Output, Don't Change the Code  
« Reply #9 on: Mar 28th, 2004, 9:14pm »
Quote Quote Modify Modify

on Mar 26th, 2004, 1:24am, towr wrote:
Well I believe it works in some compilers, maybe even most. But I'm not sure 'after-program' behavior  (when main has finished, and returned its value to the system) is well-defined. So that's why I have my doubts about my solution..

I know if the program terminates abnormally that objects are not destructed. Under normal termination, I believe the result is implementation-defined. This may depend on whether the program is compiled with debugging symbols, for example, since they often give extra information about dynamic memory. Stack object should be destroyed normally, since returning from main unwinds the stack up a level out of your program.
 
Even so, in general, there are about two stack levels above main(). One is the operating system call to the entry point, which is specifically not main(). This calls an assembly routine the compiler tacks on to your program that sets up argc and argv, allocates static storage (e.g. your B class), sets up standard library functions like the abort and terminate handlers, default new and delete functions, etc. depending on what you have linked in.
 
When main returns, it pops the stack back to this intermediate level. It should destroy static objects before calling terminate(), which exhausts the stack back to the initial operating system call that started the program and the operating system itself sees this and deallocates PIDs, memory blocks, file handles, and other operating system resources that are abstracted by the standard libraries.
 
Of course, this is what should happen. I think older MSVC++ compilers just quit from main, which is part of what made older version of Windows unstable. I do not remember for sure though.
 
Wake up, people, it's interesting! I swear!
IP Logged

x = (0x2B | ~0x2B)
x == the_question
John_Gaughan
Uberpuzzler
*****



Behold, the power of cheese!

5187759 5187759   john23874   SnowmanJTG
WWW Email

Gender: male
Posts: 767
Re: Change the Output, Don't Change the Code  
« Reply #10 on: Mar 28th, 2004, 9:19pm »
Quote Quote Modify Modify

on Mar 26th, 2004, 11:18pm, Barukh wrote:
I have a comment on your soltion: in a sense, you end up with a different code for main (and true, the restrictions are a bit ambigious...)

Not exactly. The source code is identical, but the object and machine code is not. Obviously this problem has no solution unless we can change the machine and object code. I take the requirements to mean "add to but do not change the source code." Anything else would be basically impossible.
 
towr's solution is ideal because it does not wrap around anything else, in fact, his code executes completely outside of the scope of main(), as I explained in my last post. While kelleys' solution is elegant in a way, it does go against the spirit of the problem: A's code is the same, but it is changed from a global class to a nested class.
IP Logged

x = (0x2B | ~0x2B)
x == the_question
Barukh
Uberpuzzler
*****






   


Gender: male
Posts: 2276
Re: Change the Output, Don't Change the Code  
« Reply #11 on: Mar 28th, 2004, 11:15pm »
Quote Quote Modify Modify

on Mar 28th, 2004, 9:14pm, John_Gaughan wrote:

I know if the program terminates abnormally that objects are not destructed. Under normal termination, I believe the result is implementation-defined.

B. Stroustrup, "C++ Programming Language", 3rd edition, par. 10.4.9:  
 
"A variable defined outside any function (that is, global, namespace, and class static variables) is initialized (constructed) before main() is invoked, and any such variable that has been constructed will have its destructor invoked after exit from main()".
 
IP Logged
John_Gaughan
Uberpuzzler
*****



Behold, the power of cheese!

5187759 5187759   john23874   SnowmanJTG
WWW Email

Gender: male
Posts: 767
Re: Change the Output, Don't Change the Code  
« Reply #12 on: Mar 29th, 2004, 6:30am »
Quote Quote Modify Modify

on Mar 28th, 2004, 11:15pm, Barukh wrote:
B. Stroustrup, "C++ Programming Language", 3rd edition, par. 10.4.9:  
 
"A variable defined outside any function (that is, global, namespace, and class static variables) is initialized (constructed) before main() is invoked, and any such variable that has been constructed will have its destructor invoked after exit from main()".

Right, but if main() does not exit because of a call to abort(), for example, I do not think that is guaranteed. That should basically kill the process and leave the operating system to clean up after it.
 
When main() exits normally, then yes, static and global objects' destructors will be called before termination.
IP Logged

x = (0x2B | ~0x2B)
x == the_question
kellys
Junior Member
**





   


Gender: male
Posts: 78
Re: Change the Output, Don't Change the Code  
« Reply #13 on: Mar 29th, 2004, 11:29am »
Quote Quote Modify Modify

Well... but if you can say that, then technically you can't make statements about the execution of any program, so what's the point of having a language specification?  Grin
IP Logged
towr
wu::riddles Moderator
Uberpuzzler
*****



Some people are average, some are just mean.

   


Gender: male
Posts: 13730
Re: Change the Output, Don't Change the Code  
« Reply #14 on: Mar 29th, 2004, 12:07pm »
Quote Quote Modify Modify

Sure you can..  
It has to be specified how a program reacts in the case of system-signals as well..
IP Logged

Wikipedia, Google, Mathworld, Integer sequence DB
Margit
Guest

Email

Re: Change the Output, Don't Change the Code  
« Reply #15 on: Apr 1st, 2004, 2:15am »
Quote Quote Modify Modify Remove Remove

Well, another way without changing ANY code (at least on Unix/Linux) would be to move away /usr/include and slide in your own directory version.
You can then redefine printf to do whatever you want  Grin
IP Logged
John_Gaughan
Uberpuzzler
*****



Behold, the power of cheese!

5187759 5187759   john23874   SnowmanJTG
WWW Email

Gender: male
Posts: 767
Re: Change the Output, Don't Change the Code  
« Reply #16 on: Apr 5th, 2004, 7:01am »
Quote Quote Modify Modify

on Mar 29th, 2004, 11:29am, kellys wrote:
Well... but if you can say that, then technically you can't make statements about the execution of any program, so what's the point of having a language specification?  Grin

The language specification is very clear about terminate(), abort(), returning from main(), etc. Tongue
IP Logged

x = (0x2B | ~0x2B)
x == the_question
Pages: 1  Reply Reply Notify of replies Notify of replies Send Topic Send Topic Print Print

« Previous topic | Next topic »

Powered by YaBB 1 Gold - SP 1.4!
Forum software copyright © 2000-2004 Yet another Bulletin Board