This is a thought experiment.
This question is intentionally trying to do something easy in a difficult way. I am aware of the many ways to do this using iostream, std.h, etc. Please do not suggest answers that circumvent the challenge.
Using C++,
Only using main() without any header files included, is it possible to write a program that creates a variable of any type, and outputs the value of the variable in any way, such as printing it in console, saving it to a file, anything like that?
The goal is to have a .main file that looks like:
int main(){
Some code;
return 0;
}
I've tried using C's printf but that requires a header.
The best I could come up with is saving the value to a specific space in memory then using another program to read that block. But that is somewhat circumventing the goal of outputting only from main.
This may be impossible.
If you want to have no code outside of main, in C you could do this:
int main()
{
int puts(const char *);
puts("Sup!\n");
return 0;
}
Or the same thing with printf, or any other C standard library function.
It wouldn't work in C++ though, since in C++ the puts declaration needs extern "C" to disable name mangling, which can only be used outside of functions.
There's a trick that lets you do it in C++:
int main()
{
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
return 0;
}
Variable names are not mangled, so by tricking the compiler into thinking that puts is a variable rather than a function, you can get rid of the mangling without extern C.
Technically, this satisfies your constraints:
int main() {
return 123;
}
Most OSs allow you to check a program's return code. So this communicates one number to the outside world. The available range of values may differ with the OS.
You wrote "only main", but extern "C" cannot go into a block. So, if you can live with that line outside the main function, here's the code you asked for:
extern "C" int printf(const char *fmt, ...);
int main() {
printf("Hello %s\n", "world");
return 0;
}
Proof: https://godbolt.org/z/41WhGYc79
Perhaps I haven't understood correctly, but if you want to avoid the includes/libraries then the short answer is no. A C++ header (apart from templates) is just a declaration of a possible link-time function availability and you will always need them.
Almost anything meaningful you can do with C++ (as in any programming language, even assembly) requires a call to the underlying OS and this requires a header and a library link.
Even something as simple as a char output requires thousands of lines to communicate with a device driver to output to screen.
Even if you don't include anything, the compiler will inject code (CRT) that calls the OS by using a library no matter what. Even a simple main() requires lots of calls to the OS, for actually there is no "main" entry point in the executable.
That does not exactly answer your question, but if you were doing this in C rather than C++, then for most compilers that would be a valid program (without any includes):
int main()
{
printf("hello");
return 0;
}
Although it generates a warning.
Combining two of the answers above I was able to use printf by replacing the parts of
extern int puts;
((int(*)(const char *))&puts)("Sup!\n");
With parts that would allow printf:
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", 10);
So the full code would be:
int main(){
int num = 10;
extern int printf;
((int(*)(const char *fmt, ...))&printf)("%d\n", num);
return 0;
}
I hope this helps, this is a combination of two responses not my own.
Related
I am just interested, there is one guy, who is saying that if void main() works in some compiler then it is faster than int main(). Is this true or just bs.
Edit: Okay people, I am a first-year uni student I don't know stuff deeply, it just my lector said that void main() is wrong, but another guy said that it is correct and way better if the program compiles, just tell me, this is bs or not ?. Is it stupid to use void main() or not?
void main() is not valid standard C++. Don't ever do that. Simple as that.
All valid C++ programs must return an integer from main, indicating a success or failure code to the Operating System.
And as far as performance goes, copying (or not) a single integer value takes nanoseconds (if even that much), so that's completely irrelevant.
The exception is a freestanding implementation.
int main()
or
int main(int, char**)
Are the only 2 valid entry points for standard C++, void main() is nothing.
I want to modify the string variable present in main function by the external function, by passing the address of the same.
Below is the code which I've written
void change(char * str)
{
str="Max";
}
void main()
{
char a[]="Test";
change(a);
cout<<a;
}
Please correct me if I am wrong
Please note that I am using Borland Turbo C++ 4.5.
I guess you mean pass by reference, you can simply pass the given string by reference to the external function as follows:
void modifyString( string& str)
{
//modify the string
}
inside main, you can call this function.
You want this:
void change(char * str)
{
strcpy(str,"Max");
}
Recall what a pointer is, and that the pointer itself cannot be changed only what it points to.
First of all you should not use Turbo C/C++, It was last updated long time ago,
You can change a string in a function as follows,
void change(char * str)
{
*(str+0)='M';
*(str+1)='A';
*(str+2)='X';
*(str+3)='\0';
}
int main()
{
char a[]="Hello";
change(a) ;
}
You ask,
“correct me if i am wrong”
after presenting this code:
void change(char * str)
{
str="Max";
}
void main() {
char a[]="Test";
change(a);
cout<<a;
}
So, here goes:
str="Max";
only changes the local pointer str. with a compiler conforming to the C++11 standard it won’t even compile, because str is declared as char* while the literal "Max" is of type char const [4], and C++11 does not anymore support an implicit conversion from string literal to pointer to non-const.
void main
will not compile with any standard-conforming C or C++ compiler, no matter which standard. however, visual c++ will compile it with no diagnostic. and possibly old turbo c++ did too, but note that turbo c++ predated the first C++ standard (which came in 1998). the standard requires int result type for main for an ordinary hosted C++ implementation.
cout<<a;
will not compile with a standard-conforming compiler without including <iostream> and having a using declaration or directive. note that this changed with the standardization. before the 1998 standard, in ARM C++, you could include <iostream.h> and use unqualified cout.
A proper way to do your program, in modern C++, is
#include <iostream> // std::cout, std::endl
#include <string> // std::string
using namespace std;
string foo() { return "Max"; }
int main()
{
string a = "Test";
a = foo(); // Changed!
cout << a << endl;
}
another answer, which as I’m writing this you have selected as “solution”, recommends using raw pointers and strcpy, instead of std::string. using raw pointers and arrays is advice that will make you unhappy if you follow it. for example, it’s very easy to inadvertently write beyond the end of the provided buffer, with disastrous effects. ownership handling is exceedingly difficult to do correctly, and so on. the advice was presumably given in the Stack Overflow tradition of answering the literal question with no regard for what the question was really about, which is a good way to obtain Stack Overflow reputation points (it beats me what is so desirable about them, the silly T-shirts or whatever are really not worth it), at the cost of creating severe problems for others, sort of like maiming a few bystanders in order to steal a small bar of chocolate.
I was wondering if there was a simple way to write an alias of a c++ class function. For instance, if I have some list container object, a logical function would be
int list::length() { return len; }
But another logical alias that programmers might use could be
int list::size() { return len; }
So, instead of writing both functions with their full body, is there any way to make list::size() an alias of list::length() such that it isn't a duplicate when compiled, but rather references the same function?
I've read that you can do this with #define, but I don't want to cause any confusion with other code-names somewhere totally out of scope (i.e. a 'size' variable).
I've also read that function pointers can fix it, but that isn't exactly an alias (since it has to apply de-referencing), nor can function pointers be given a declaration, giving it a confusing help-line to users (I would think), plus the confusion if ever I need to nest my code inside another object (I have to adjust the scope).
One of my guesses is, will the following be taken as a direct function alias by most optimizing compilers:
inline int list::length() { return len; }
inline int list::size() { return length(); }
Or, is there any strict 'alias' syntax for c++? (I couldn't find any - wasn't sure)
So then, what would be the most efficient way of doing this?
EDIT: I've accepted the answer simply to wrap up the question, since it's only a curiosity of mine. Anyone with good information, please add comments or answer, and I may even change my answer.
I would not use the preprocessor and #define to do this. In general preprocessor should be a last resort in C++. See this C++ FAQ on inline functions which also contains a section on the various evils of using macros of the preprocessor.
The approach I would use would be to have a function that will have several different aliases with a more complicated function and interface you would do something like the following:
int list::length(string xString, int iValue) {
int iReturnValue = 0; // init the return value
// do stuff with xString and iValue and other things
return iReturnValue;
}
Then do something like the following for an alias.
inline int list::size(string xString, int iValue) {return length(xString, iValue);}
The inline should basically just replace the alias with the actual function call.
See also this stack overflow posting Giving a function implementation more than one name. It provides some reasons why you might not want to do this.
Here is what my book says:
char *p="Hello"; //pointer is variable, string is constant
*p='M'; // error
p="bye"; // works
Well, in C my second line does not give me any error, Neither in C++.
I am using Turbo C++ on windows 7. Now is the above thing true if i try in gcc or something else.
Also on the similar lines if the above code is correctly interpreted by the book,
#include<iostream.h>
void display(char*);
void display(const char*);
void main()
{
char* ch1="hello";
const char *ch2="bye";
display(ch1);
display(ch2);
}
void display(char* p)
{
cout << p << endl;
}
void display(const char* p)
{
cout << p << endl;
}
Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?
(Though i get the output Hello bye on turbo +windows.)
Which one is correct?
The language specification is not a promise that compilers make to you, but a mutual contract that you and compilers both sign onto. (Metaphorically speaking, of course. Obviously it's not a literally legally binding contract.) If you violate the contract by writing *p='M';, then you've triggered "undefined behavior", and you can't expect any specific behavior from the compiler: maybe it will be strict about it and give you a compile error, maybe it will just go wonky at run-time . . . you didn't hold up your end of the bargain, and it's allowed to do literally whatever it wants now. See also: http://catb.org/jargon/html/N/nasal-demons.html.
Question:
“Now is my book considering char* and const char* the same because if it is then the above code shall not work, since arguments will be the same?”
Well you’re probably misrepresenting your book.
It probably does not consider those types to be the same, because they are not the same.
Now to your code:
#include<iostream.h>
[iostream.h] is not part of standard C++. C++ was standardized in 1998, and that standardization dispensed with the ARM era's [iostream.h]. So a modern compiler will likely choke on that.
As a workaround, when you get yourself a less antique compiler, you might do …
#include <iostream>
using namespace std;
Next,
void display(char*);
void display(const char*);
Declaring functions at the top of the file generally just yields extra work. It often means maintaining two declarations of the function. When you could have dealt with just one declaration.
void main()
In standard C and standard C++ main is not allowed to have any other result type than int.
Visual C++ is one compiler that, as a language extension, permits void.
However, it’s quite silly to use that possibility since it is more to write and just makes the code non-standard and likely to not compile with other compilers.
{
char* ch1="hello";
By C++11 rules the above will not compile. It was deprecated in C++98 and removed in C++11. However, AFAIK current compilers still allow it, but some have a warning that can be turned on.
const char *ch2="bye";
display(ch1);
display(ch2);
}
The above is OK, although it would not hurt to add an extra const, like
const char* const ch2="bye";
char* ch1="hello";
is deprecated in C++. The correct way is const char*. Because "hello" is stored in a read only region. Also, int main() or int main(int, char**) is the correct way of defining main().
Don't use Turbo C, it's an outdated compiler. Go for gcc or MSVC. Also, don't use books which provides such incorrect information.
char *p="Hello"; //pointer is variable, string is constant
This code is allowed, because it has been valid since long before the C language got a const keyword.
In order not to break old code, the C and C++ standards just documented that this should work like before.
However, if you write new code you should use the proper form const char*.
I've got some problems/misunderstandings with arrays in C++.
int myArray[30];
myArray[1]=2;
myArray[2]=4;
This is spitting out a lot of compiler errors. I don't think it is necessary to include them here as this is an easy question for everybody with experience in C(++) I guess
Why doesn't this work?
Is there a way to create a "dynamic" array that has a fixed ammount of values (so no malloc needed) but where I can change the values during runtime?
I'm guessing you have that outside of a function.
You are allowed to define variables outside of a function. You can even call arbitrary code outside of a function provided it is part of a variable definition.
// legal outside of a function
int myArray[30];
int x = arbitrary_code();
void foo()
{
}
But you cannot have arbitrary statements or expressions outside of a function.
// ILLEGAL outside a function
myArray[1] = 5;
void foo()
{
// But legal inside a function
myArray[2] = 10;
}
Are you saying that this doesn't compile:
int main() {
int myArray[30];
myArray[1]=2;
myArray[2]=4;
}
If it doesn't, you have something wrong with your compiler setup. As I said in my comment, we need to see the error messages.