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.
Related
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.
#include <iostream>
#include <string>
using namespace std;
class CExample {
public:
int a,b,c;
void setvalue(int n, int m);
void multiply() {
c = a*b;
cout<< c <<endl;
};
};
void CExample::setvalue(int n, int m){
a = n; b = m;
}
int main( )
{
CExample *d = new CExample[1];
d[0].setvalue(2,30);
d[0].multiply();
d[1].setvalue(2,30);
d[1].multiply();
d[2].setvalue(2,30);
d[2].multiply();
delete[] d;
return 0;
}
Since I have only allocate 1 Memory resource for Array d, I ought to encounter error when manipulating d[2]. However, the compiler didn't report error or warning. And the result is correct.
Can someone explain why it works?
Thanks
Yes, it is the magic of undefined behavior. Thanks for all of you.
The C++ compiler can't and won't catch all the possible way you could write incorrect code.
And while running, a C++ program will usually not throw an error the moment you access memory out of bounds. The language was not designed to protect the programmer from doing bad things.
So when a program does something like this... which is undefined behavior... anything might happen. That "anything" can include appearing to work "correctly". Or weird behavior might appear right away. But either way it's wrong. If it appears to work, that's only by luck.
And in practice it will also likely be corrupting memory somewhere which will lead to other problems eventually. Maybe the problems don't have time to manifest in small example programs. But the larger the program, the more likely some kind of bad symptom will show up.
In the end, C++ puts a significant degree of responsibility on the programmer to write correct code which doesn't do things like going outside of array bounds.
"Can someone explain why it works?" -- You believe the code works.
"I ought to encounter error when manipulating d[2]" -- You believe the code should do something other than what it does.
You are making two conflicting claims. You are saying both that the code works and that it should do something other than what it does. These cannot both be true.
As you know, your code has a bug. So it's not surprising that it doesn't do what you expect.
You operate on a un-alloc memory, it's a undefined behavior.
It's a run-time error, so compiler can't catch it.
With valgrind, a memory check tool, you will get "Invalid write" errors.
I didn't found this question in Stack Overflow or Google, so sorry if it's a duplicate.
As I know, variables in C/C++ are not initialized. But recently a strange situation occur to me when using pointers. See the code below:
#include <iostream>
using namespace std;
struct Test {
int i;
};
struct Box{
Test *var;
};
int main() {
Box *t = new Box;
cout << t->var;
}
In Windows, the output I get is something like (what is expected):
0x3e0178
But, in Unix systems, the output is:
0x0
Why this happen? Does the compiler initialize the pointers in a recursive way when new is invoked in Unix systems?
Also, with common variables the same happens. For the code below, the results are 0 in Unix systems and 4385838 in Windows:
int main() {
int i;
cout << i << endl;
}
UPDATE
In another test, the behavior this time was the same in both systems: the pointer p points to a random address in the memory.
int main() {
int *p;
cout << p;
}
Just to explain my question: I know we have to initialize the variables before using it, but a student was asking me why his program works fine in Unix systems and not in Windows. I found this pointer issue in his program, and I want to give a feedback.
In all modern (multiuser) operating systems, memory received directly form the os is zeroed, in order to avoid information leakage. What happens, is probably the Unix systems, because far less startup code must be run to set up a proper C runtime environment, main() by dumb luck got virgin memory, not reusing stack space previously used for a different function, to store i. The other possible explanation is, someone just stored a 0 there before.
Anyway, don't rely on it for heavens sake.
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.
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*.