I find about int main definition, but not of void main in introduction of c++ programming language. I tried reading all the articles written in introduction of c++ programming language.
void main has never been valid in either C or C++.
C++11 §3.6.1/2:
” An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined. All implementations shall allow both of the following definitions of main:
int main() { /* ... */ }
and
int main(int argc, char* argv[]) { /* ... */ }
…
C++11 §3.6.1/5:
” A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing
return 0;
The value 0 is one value that indicates process success. The value EXIT_SUCCESS from <stdlib.h> may be 0 or some other value. The value EXIT_FAILURE indicates process failure.
Using void main is not standard, although there is some history regarding why some compilers allow it.
The following is from a 2008 post on programingforums.org:
In 1971, Denis Ritchie (who was working alongside Ken Thomson
developing Unix) produced a "new B" by add support for the character
type, and modified the early B compilers to output machine code. In
1972, "new B" was renamed to C. A preprocessor was added in 1973 or so
and another programmer in the team produced the "portable I/O
package", which was later renamed to the C "standard I/O routines".
Hence the first version of C was born: it supported only char,
integer, and pointer types. There was no void keyword.
Denis Ritchie and Brian Kernighan worked together to enhance C. Later
versions of C introduced more of the standard library, such as
malloc() - which originally returned pointer to char, as there was no
void pointer. Hence it was always necessary in early versions of C to
cast the return from malloc(). Support for floating point was also
added. This became what is known as Kernighan and Ritchie (K&R) C.
In the early 1980s, a decision was made to ratify C as a standard,
leading to the development of the first ANSI Standard in 1989 (then
ratified as an ISO standard in 1990). In the committee process leading
to the standard, a number of changes were made: in particular the void
keyword was introduced, the form of function prototypes was changed.
During the standardisation process, several commercial compilers were
developed. Some of these supported void main() as a work-around for
compiler diagnostics about falling off the end of main(). They lobbied
unsuccessfully for this to be supported by the C standard, but that
was not accepted as other vendors considered it added no significant
or useful new functionality. Later, in the early 1990s, when "standard
compliance" became a marketing tool, they unleashed lawyers on the
standard and found the wording loop-hole that - they then claimed -
allows void main() to be considered as standard.
During the C standardisation process, Bjarne Stroustrup started work
on the development of C++, and published the ARM (Annotated Reference
Manual) with Margaret Ellis in 1990. Since that happened in parallel
with the minor flurry associated with void main(), that feature was
never part of C++. The ARM was the basis for development of the C++
standard, which was finally ratified by ANSI in 1998 and ISO in 1999.
During development of the 1999 C standard, there was some discussion
about void main(), but it never gained traction - the push in favour
was political, and overall consensus was apparently that it offered
little technical benefit. Hence the 1999 C standard explicitly
disallows it.
I am learning C, and after starting out learning C++ as my first compiled language, I decided to "go back to basics" and learn C.
There are two questions that I have concerning the ways each language deals with functions.
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
For example,
int main()
{
donothing();
return 0;
}
void donothing() { }
the above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this? Isn't C++ mostly just an extension on C, and should be mostly "backward compatible"?
Secondly, the book that I found (Link to pdf) does not seem to state a return type for the main function. I check around and found other books and websites and these also commonly do not specify return types for the main function. If I try to compile a program that does not specify a return type for main, it compiles fine (although with some warnings) in a C compiler, but it doesn't compile in a C++ compiler. Again, why is that? Is it better style to always specify the return type as an integer rather than leaving it out?
Thanks for any help, and just as a side note, if anyone can suggest a better book that I should buy that would be great!
Firstly, why does C "not care" about the scope that functions are defined in, whereas C++ does?
Actually, C does care. It’s just that C89 allows implicitly declared functions and infers its return type as int and its parameters from usage. C99 no longer allows this.
So in your example it’s as if you had declared a prototype as
int dosomething();
The same goes for implicit return types: missing return types are inferred as int in C89 but not C99. Compiling your code with gcc -std=c99 -pedantic-errors yields something similar to the following:
main.c: In function 'main':
main.c:2:5: error: implicit declaration of function 'donothing' [-Wimplicit-function-declaration]
main.c: At top level:
main.c:5:6: error: conflicting types for 'donothing'
main.c:2:5: note: previous implicit declaration of 'donothing' was her
For the record, here’s the code I’ve used:
int main() {
donothing();
return 0;
}
void donothing() { }
It's because C++ supports optional parameters. When C++ sees donothing(); it can't tell if donothing is:
void donothing(void);
or
void donothing(int j = 0);
It has to pass different parameters in these two cases. It's also because C++ is more strongly typed than C.
int main() {
donothing();
return 0;
}
void donothing() { }
Nice minimum working example.
With gcc 4.2.1, the above code gets a warning regarding the conflicting types for void donothing() with default compiler settings. That's what the C89 standard says to do with this kind of problem. With clang, the above code fails on void donothing(). The C99 standard is a bit stricter.
It's a good idea to compile your C++ code with warnings enabled and set to a high threshold. This becomes even more important in C. Compile with warnings enabled and treat implicit function declarations as an error.
Another difference between C and C++: In C++ there is no difference between the declarations void donothing(void); and void donothing(); There is a huge difference between these two in C. The first is a function that takes no parameters. The latter is a function with an unspecified calling sequence.
Never use donothing() to specify a function that takes no arguments. The compiler has no choice but to accept donothing(1,2,3) with this form. It knows to reject donothing(1,2,3) when the function is declared as void donothing(void).
he above will not compile in a C++ compiler, whereas it will compile in a C compiler. Why is this?
Because C++ requires a declaration (or definition) of the function to be in scope at the point of the call.
Isn't C++ mostly just an extension on C
Not exactly. It was originally based on a set of C extensions, and it refers to the C standard (with a few modifications) for the definitions of the contents of standard headers from C. The C++ "language itself" is similar to C but is not an extension of it.
and should be mostly "backward compatible"?
Emphasis on "mostly". Most C features are available in C++, and a lot of the ones removed were to make C++ a more strictly typed language than C. But there's no particular expectation that C code will compile as C++. Even when it does, it doesn't always have the same meaning.
I check around and found other books and websites and these also commonly do not specify return types for the main function
The C and C++ standards have always said that main returns int.
In C89, if you omit the return type of a function it is assumed to be int. C++ and C99 both lack this implicit int return type, but a lot of C tutorial books and tutorials (and compilers and code) still use the C89 standard.
C has some allowances for implementations to accept other return types, but not for portable programs to demand them. Both languages have a concept of a "freestanding implementation", which can define program entry and exit any way it likes -- again, because this is specific to an implementation it's not suitable for general teaching of C.
IMO, even if you're going to use a C89 compiler it's worth writing your code to also be valid C99 (especially if you have a C99 compiler available to check it). The features removed in C99 were considered harmful in some way. It's not worth even trying to write code that's both C and C++, except in header files intended for inter-operation between the languages.
I decided to "go back to basics" and learn C.
You shouldn't think of C as a prerequisite or "basic form" of C++, because it isn't. It is a simpler language, though, with fewer features for higher-level programming. This is often cited as an advantage of C by users of C. And an advantage of C++ by users of C++. Sometimes those users are the same people using the languages for different purposes.
Typical coding style in C is different from typical coding style in C++, and so you might well learn certain basics more readily in C than in C++. It is possible to learn low-level programming using C++, and the code you write when you do so may or may not end up looking a lot like C code.
So, what you learn while learning C may or may not inform the way you write C++. If it does, that may or may not be for the better.
C++ has changed these rules on purpose, to make C++ a more typesafe language.
C.1.4 Clause 5: expressions [diff.expr]
5.2.2
Change: Implicit declaration of functions is not allowed
Rationale: The type-safe nature of C++.
Effect on original feature: Deletion of semantically well-defined feature. Note: the original feature was
labeled as “obsolescent” in ISO C.
Difficulty of converting: Syntactic transformation. Facilities for producing explicit function declarations
are fairly widespread commercially.
How widely used: Common.
You can find other similar changes in appendix C of this Draft C++ standard
Isn't C++ mostly just an extension on C
No. If you think of C++ as "C with Classes", you're doing it very, very wrong. Whilst strictly, most valid C is valid C++, there's virtually no good C that's good C++. The reality is that good C++ code is vastly different to what you'd see as good C code.
Firstly, why does C "not care" about the scope that functions are
defined in, whereas C++ does?
Essentially, because not enforcing the same rules as C++ makes doing this in C hideously unsafe and in fact, nobody sane should ever do that. C99 tightened this up, along with implicit-int and other defects in the C language.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Difference between void main and int main?
Why is
void main() {
//return void
}
bad?
The other day I typed this and someone pointed out to me that it is wrong to do so. I was so confused. I have been writing like this for a while now, I know it isn't C++ standard, but the compiler doesn't give out any warnings. Why is this wrong?
Because the compiler you use does not error out on it, it doesn't mean other compilers won't. You know its not standard, after all...
It is wrong exactly because it is not standard. One compiler might accept this, another might complain, and the pedantic believers will burn your ass on the stake anyways.
Because every program should indicate to other programs whether or not it completed successfully, or if there was some sort of error, and you can't do that if your main doesn't return anything.
Plus, the standard says that main should return an int.
It's wrong because the standard (at least C++03) states that main should return an int (for hosted environments, that is - freestanding environments like embedded systems can pretty well do whatever they want). From 3.6.1 Main function, paragraph 2:
An implementation shall not predefine the main function. This function shall not be overloaded. It shall have a return type of type int, but otherwise its type is implementation-defined.
All implementations shall allow both of the following definitions of main: int main() { /* ... */ } and int main(int argc, char* argv[]) { /* ... */ }.
If you value portability at all (and you should), you should writ code that conforms with the standard as much as practicable.
Undefined behaviour like:
x = x++ + --x;
may work (for whatever definition of "work" you have) under some circumstances as well, that doesn't make it a good idea :-)
It's nonstandard.
i.e. you're not writing "C++" (as it was conceived) when you write this. It might look like C++, but you're not following the rules, so you're not actually writing C++.
Also its result is undefined in most cases.
Unlike in other languages like C++ or C#, where "bad" behavior causes errors, C++ allows anything to happen when an erroneous construct is used. So you can't depend on the compiler doing the "correct" thing, because it may do so one time, but not another.
In general, you want to avoid undefined behavior, so you shouldn't do this.
Why has setting the entry point's return type to void in C++ always been discouraged, and was later removed by the standard and is prohibited by modern compilers? Why is it considered bad practice?
Now, as I understand C# and Java both allow the entry point's return type to be void i.e
static void main(String[] args) /* Java */
static void Main(string[] args) /* C# */
And C# and Java programmers do not consider it bad practice, they use it often in fact.
Other languages which are (only intended to be, I doubt C++ will be succeeded in this decade, at least) possible successors of C++ like the D Programming Language or Vala also allow a void main(). So as you can see, I doubt the C++ community removed it from the standard because it was too obscure or unpopular.
So my question is, Why did the C++ Community Remove void main()? What was wrong with it?
The C++ standards committee likely chose to require int main() because of the large body of existing code that expected to use a return statement to return a specific exit code to the runtime system. It would be unreasonable to expect all existing code to change to use exit() instead, so int main() was made a requirement in the standard.
A language such as Java, when it was designed, did not have any body of existing code that it needed to remain compatible with. Therefore, the designers could choose void main() and require the use of System.exit() for non-zero exit codes.
So, the thing that would be "wrong" with choosing void main() for the C++ standard would be that it would break existing code that expected to use return and an exit code value from main().
C++ has never permitted void main(), though some compilers might permit it either as an extension or just because they don't diagnose it.
Similarly C has never permitted void main() other than as an extension; the same 1989 standard that introduced the void keyword defined the two standard definitions for main: int main(void) and int main(int argc, char *argv[]).
Other languages permit it because, well, they're other languages.
There is no particular advantage in being able to write void main() rather than int main(). You don't even need to explicitly return a value; falling off the end of main is equivalent to return 0; (in C++, and in C starting with C99).
You generally want to know the exit status of your program. That's the reason why you have the int main() -- you return your exit status.
It's wrong because this is not what the C++ Standard specifies as a legal main. Nobody cares about what the other languages specify. For C++ programs, only the C++ Standard is relevant, and it says int.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed last month.
Improve this question
Is there something that I can do in C but I can't do in C++ ?
I stumbled upon the question in a sample interview questions site.
Declare a variable named 'class', as in:
int class = 0;
...that is there anything I can do in C but not in C++.
Both languages are Turing complete, so in theory you can code up equally functional applications in both.
OTOH, C++ is not a superset of C. Especially C99 has some features that C++ does not have. E.g. designated initializers, variable length arrays in structs and as automatic variables. Depending on your "anything", this could be something that C++ cannot do but C can.
In C, you can create array literals ("compound literal"), but in C++ you cannot
/* p points to the first element of an array of 4 int */
int *p = (int[]){1, 2, 3, 4};
You can also create an array with size not yet known at compile time, but C++ has no such possibility ("variable length array"):
// create array. size is known at runtime only.
int p[rand() % 5 + 1];
int new = 0;
works in C, but obviously can't work in C++ because 'new' is a reserved word.
There are some other 'tricks' with reserved words, but other than that, you can pretty much do everything in C that you can do in C++.
Quite a few things. For example, in C you can write code like this:
void * v = 0;
char * p = v;
and you can create arrays like this:
int main() {
int n = 42;
int a[n];
return 0;
}
neither of which will compile under C++.
C++ lacks C99's restrict qualifier. Therefore, there is no way to tell the compiler to perform optimizations based around knowing that pointers aren't aliases.
There are some things you can say in C wihch you can't in C++ (because C++ has stricter syntax-checking, and C has a more extensive 'legacy' syntax).
Also, there may be some run-time environments (O/S+library+compiler) which support C but not C++, so you can do C on those platforms where you can't do C++.
Syntactically there are a few things you could write in C that wouldn't compile in C++ (See Incompatibilities Between ISO C and ISO C++ for excruciating details.). If you're asking at a higher level, if there is some program that it's possible to write in C, but not possible to write in C++, then the answer is "No."
Actually, I can think of one example:
When you create a library (.lib file or .dll file) to be shared by other applications, you're better off using C instead of C++ because the results are more portable. You can do this within a C++ compiler by using an 'extern "C"' block though.
Specifically, C++ has a quirk where there is no standard convention for name mangling - for translating your library's function signatures into more low level names used by the compiler. So for example if you have a function like 'int addNumbers (int a, int b)', different C++ compilers may translate this function into different names, which can lead to problems when you want to import the library. If you use a C compiler or surround your library importing and exporting code with a C block though you won't see this problem, since there is only one way to mangle function names in C.
In 'C' you don't need forward declarations. This allows you to pass parameters which are interpreted incorrectly. (Not that this is a great feature, but you can't do it in C++)
in file A:
float sum(float a, float b)
{
return a+b;
}
in file B
main()
{
printf("%f\n", sum(1,2));
}
with C, this compiles, but prints 0.000
with C++, you need a float sum(float,float); before the printf, and it gives the expected result.
You can sparsely initialize arrays in C. I like to use it for mapping int->sometype for relatively dense static maps where an unmapped value can be interpreted as 0:
int my_array[] = { [1] = 3, [4] = 2 };
printf("%d %d %d\n", sizeof my_array, my_array[0], my_array[1]);
/* prints 20, 0, 3 */
The 1998 C++ standard has a list of incompatibilities with the 1990 C standard that is 13 pages long (Annex C). Granted, it's not a lot, compared to the amount of pages that describe the languages, but still covers quit a bit of ground.
Quick summary of the kind of differences that it lists:
New keywords are added (any C program that uses them as identifiers is not C++)
Type of character literal changed from int to char (compare sizeof('a') in C and C++!)
String literals made const (can't do char* q = expr ? "abc" : "de";)
"Tentative definitions" are removed from the language.
"Compatible types" are removed from the language.
Converting from void* to any other pointer now requires casting.
Converting from any const/volatile pointer to void* now requires casting.
"Implicit declarations" are removed from the language.
Expressions can no longer create new types (as in p = (void*)(struct x {int i;} *)0; )
results of some expressions became lvalues (compare sizeof(0, arr) for char arr[100];)
...that was the first 3 pages of Annex C.
If you go to the 1999 C standard, the differences are going to take forever to describe. Although C++0x did include some of C99 features, many of them are just inherently incompatible, like the complex type.
In C, you can declare variables with the following names:
bool, class, new, delete, template, typename, this, throw, catch,
typeid, operator, virtual, static_cast, reinterpret_cast,
dynamic_cast, mutable, public, private, protected, friend; //many more
then you can do these:
int namespace = private + protected + public;
int decltype = static_cast + dynamic_cast + reinterpret_cast;
int constexpr = (new + delete) * (template + typename);
All of them are keywords in C++11.
You can do almost everything in any of the programming languages. Of course the way of expressing it will vary, as well as the amount of code, clarity of code, ease of further maintenance. Some tasks can be coded with few lines in Prolog and few pages of code in C++, and so on.
Some limiting factors are the available libraries, available compilers, and low-level issues. However when you consider C and C++ on a typical PC, then there is no difference in things that can be done in either of them.
Unless of course you were asking for the differences between C and C++ - for these other people have given you the idea.
char *c = malloc(sizeof(char));
is valid in C, not C++ i.e. automatically casting void*. This of course is a syntax issue, not so much as what you can and cannot _do_ (i.e. accomplish).
If the criteria is to solve a particular programming problem then both will do the job although it may be a bit easier in some cases to do it in C++ due to the higher level of abstraction
Is this referring to the latest C standard? The original C standard (ANSI 1989 or ISO 1990, with 1995 updates) is fairly close to being a subset of C++. There's differences, but they're mostly contrived (the biggest exception probably being that void * converts freely with any data pointer in C but not in C++).
However, a new C standard came out in 1999, some time after I'd stopped doing anything in the most modern C. It had new features, some of which are going into the C++ standard due this year or next, but not all.
C++ is obviously not a superset of C for a very simple reason: New keywords have been added to C++
class, virtual, new, etc and thus can no more be used as identifiers in C++.
Some of the reasons are subtler.
You can find an exhaustive answer to this question on Bjarn Stroustrup's website:
The C++ programming language | Appendix B
C can have a function with an unspecified amount of arguments. Disclaimer that this is bad practice and shouldn't be used, but present and interesting nonetheless:
void x() { }
in C means a function with an unspecified amount of parameters. This is as opposed to
void x(void) { }
Which means a function with 0 parameters in C. In C++ both functions mean the same thing and take 0 arguments.
Using the unspecified parameter count in C, you could access the parameters the same way you would using variable arguments.
So:
void x()
{
}
int main()
{
// This line would compile in C and C++
x();
// This line compiles in C but not C++
x(5, 7)
return 0;
}
That is why you should try to write void as a parameter instead of leaving them blank. In C always explicitly write void so you don't have issues, and inC++ both are equivalent so it doesn't matter but it's nice to be explicit.
Many aspects of hardware-related embedded ("freestanding") systems programming are only possible in C.
[Major difference] In C you can do union type punning, which is done is pretty much every professional microcontroller hardware peripheral register map ever written. This is undefined behavior in C++.
In C you can use the de facto standard freestanding implementation-defined form of main() as void main (void). This is not allowed in C++ because of artificial restrictions. You must either have your bare metal C++ program return a value to la-la-land or name the procedure entered at startup something else than main.
When using structs allocated with static storage duration in C, you can have them quickly initialized with just a "zero out" (.bss initialization). Doing the same in C++ with structs/classes will mean that member variables get "zeroed out" too, but in addition default constructors will get called, leading to needlessly slow program startup.
[Major difference] In C you can declare const variables without initializing them. This is very useful for const volatile variables declared in EEPROM/flash, to be written to in run-time by bootloaders and similar. In C++ you are forced to initialize the variables, which in turn forces default values to get burned into EEPROM/flash, leading to slower programming time and slightly more physical memory wear.
[Major difference] No standard library function in C performs heap allocation silently/implicitly, apart from the malloc family (and in C23, strdup as well). In C++, silent heap allocation is very common in standard library functions, making those libraries unsuitable for embedded systems.
restrict pointers are possible to use in C for various micro-optimizations.
C allows pointers to VLA, which can help improving readability and diagnostics. On the other hand, C++ doesn't allow objects of VLA type, which is a good thing in embedded systems. C compilers can optionally refuse to implement certain aspects of VLA depending on their standard compliance (C99 vs C11/C17 vs C23 - C23 being the most suitable for embedded systems in regards of VLA).
C++ didn't support designated initializers until C++20 and these are quite handy to have in all manner of situations. (C++ does support initializer lists with named members inside constructors, however.)
C doesn't allow exception handling and I'd say that's a huge benefit in embedded systems. You'll want to avoid opening that can of worms inside your deterministic firmware. Error handling in C is rather handled gracefully by returning an error code from one module to its caller and then further down the line as needed. Instead of violently crashing down the dependency chain if left unhandled, just like the average run-away code bug would. It is however possible to write exception-free code in C++ too, if done with great care.
(Major) "Forever loops" is an important concept in programming, particularly so in embedded systems programming, where even empty loops with no side effects are common. And yet C++ doesn't support that. Optimizing away a "while(1);" in C++0x. A perfectly valid embedded systems program might look like init_interrupts(); for(;;){}. However, the C++ committee have apparently not taken such very common scenarios in consideration, so you can't write such programs in C++.
Benefits of C++ over C in hardware-related programming:
Inline assembler is standardized in C++, since C++ predicted that the programs written in it would get executed on computers. C did make no such prediction and so inline assembler/running your C program on a computer is not yet supported even in C23. It's just sad. (Similarly sad, neither language has a standardized interrupt keyword.)
C++ historically has a much better system for static assertions than C, which didn't support them proper until C11 (and further support is added in C23).
C++ guarantees a diagnostic message when doing implicit pointer conversions to/from void*. C does not. And void pointers are generally to be avoided in embedded systems.
You cannot call main() recursively in C++.
Conditional expressions with logic/relational/equality operators in C++ result in bool.
Character constants ('A') are of type char in C++, which saves a tiny bit of memory.
"If it can't be done in assembly, it's not worth doing!"
ok, humor aside, I THINK the OP is asking syntactically, rather than operationally.
I think that there are a few obscure things that are legal in C (at least C89) that are not legal in C++, or at least deprecated... But (if they exist) they're pretty obscure. C++ is functionally a superset of C.
C++ does not support named struct member initialization but in C you can do:
struct { int x, y; } a = { .x = 3 };
You can also combine this with the feature shown by Matt Havener:
struct { int a[3], b; } w[] = { [0].a = {1}, [1].a[0] = 2 };
The short answer is...no, not really. See http://www.research.att.com/~bs/bs_faq.html#difference