Making a program compile itself

So, I have been looking into the system() function in the <stdlib.h> header file, and I found some interesting things.

One, it is heavily OS-dependent, you can only use OS-specific commands in it, because it calls on the operating system of your computer. Therefore, if you have a Unix system and you're sending it to someone with a Windows computer, it will not work.

Two, I can now write programs that compile themselves! All I need is this simple line:
system ("c++ -std=c++2a -g -o executable program.cc");
I tried making the program run itself too, but...that didn't go so well. It just kept running itself until I hit [tt]Ctrl-c]/tt]!

Three, I am not sure if this is advisable, because it seems like it could be a security hazard, if a program can call on the operating system like that. As exemplified by the infinite run issue.

Four, if it is not a security hazard or anything like that, I have just made my hobby a whole lot more fun, because I can now write Bash scripts into .txt files, load them into a program, and watch fun happen!

Any comments, questions, concerns...?
Yes, system() is a security issue, but this is irrelevant if you use it on your computer to compile and load your code. What are you going to do, hack yourself?

Compiling and executing arbitrary code is only dangerous when the code you're loading comes from other people. [1]
system() is only dangerous when the person who wrote the code and person who controls the computer the program runs on are not the same, for a similar reason as above: someone might have put an executable in a different location with the intent to produce an unexpected behavior.


[1] https://en.wikipedia.org/wiki/Arbitrary_code_execution
Last edited on
Ah, I see now. Thanks! Now I can be lazy and make my programs compile themselves, all I'll have to do now is hit Cmd-R, sit back, and watch stuff happen!

I am not planning to hack myself (!!!), or let other people hack me, so I will be careful about checking code I copy off of random websites, or I could not be lazy and write my own code instead of using other people's... ;)
Therefore, if you have a Unix system and you're sending it to someone with a Windows computer, it will not work.


and obviously vice-versa.

Never, ever use system() in production code that is to be used on different computers.

the concern I have is more mechanical ... windows specifically outright refuses to let you over-write an exe file that is running, and it takes significant effort to go around it (if you even can now, last time I did it was some versions back, xp maybe?)
and unix may or may not tolerate it, not sure.
in that vein all I can think of to do is have it compile its library (detect update) (dll - style) exit itself and restart, with the library holding all the real code beyond the self compile.
but if you can get it working, have fun.
seeplus,
I won't, thanks!

jonnin,
It works fine on my Mac...I use TextMate for editing code, and it has a function whereby you can hit Cmd-R and it creates a temporary executable and runs the program for you. It only runs output, but it's enough to compile the program. Then all I need to do is double click on the executable and it runs in Terminal.

For example:
1
2
3
4
5
6
7
8
9
#include <iostream>
int main ()
{
    int num {4};
    std::cout << "Number is: " << num << std::endl;
    
    system ("c++ -std=c++2a test.cc");
    return 0;
}


When I double click on the executable a.out, it gives me this:
Last login: Mon Mar 21 09:14:51 on ttys000
prandtl:~ agentmax$ /nas2.1/home/Stored\ Documents/Programs/C++/a.out ; exit;
Number is: 4
clang: error: no such file or directory: 'test.cc'
clang: error: no input files
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.


[Process completed]
It runs, but it also tries to run the system() command and recompile the executable while running...and like you said, it doesn't work. But it runs the rest of the program.
Last edited on
Jonnin's talking about live code editing -- i.e., you write the code and the program updates its behavior as you go, without having to restart the whole thing.

This is maybe useful for programming video games.
I call that self modifying code. Not sure how useful it is, or if its even doable anymore.
but actually I was saying windows specifically hates on modifying an exe that is currently running. Try it in visual studio, run something, then try to compile it while its going, and it will fail on the linker (can't write to exe). I think linux and such do the same by default, but I haven't tried in a while and its fuzzy memory there.

Yes, system simply tells the os something and then moves on. You can type anything in the input and it will be 'successful' in C++ terms even if it failed at the OS level. System is a crude tool.
but actually I was saying windows specifically hates on modifying an exe that is currently running. Try it in visual studio, run something, then try to compile it while its going, and it will fail on the linker (can't write to exe).
Even if you could write to the executable, that doesn't mean the OS would reload it.

Self-modifying code is still very much possible. That's how function hooking and JIT compilation works. I'm not sure what OP is thinking of doing, but his idea can be used to make a rudimentary JIT. Write some code to disk, invoke the compiler to produce a dynamic library, load it, and run it.
I call that self modifying code. Not sure how useful it is, or if its even doable anymore.

Oh, my mistake. But the library thing you were talking about still works. The trick is that the host process needs to rename the library before getting the function pointers out of it.
In UNIX, you can overwrite your executable if you delete the old file and then write the new one. The executing program will continue to use the old file via its inode. The file won't truly delete until the program terminates.

But if you delete and rewrite the file then there's a short period when the file doesn't exist or is incomplete. To avoid this, you write the new file to a temp file in the same directory and then rename it. Renaming is atomic, so anything that opens the file will get either the old one or the new one in its entirety. We use this method at work when updating various config and data files.
dhayden,
Ah, I think I see what you're talking about...I'm not sure how to actually do that, but I'll consult my Unix manual and see what it says.

It sounds like it would be really useful for, like you said, updating programs or something like that.

Note: I tried having the program run itself, with
system ("./executable");
but it made it keep running infinitely, so...
Topic archived. No new replies allowed.