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.
-
9You can make Linus Torvald happy in C... beyond that, not really. – user54650 Feb 04 '09 at 20:03
-
I think majority of the differences will be about syntax... – yusuf Feb 04 '09 at 20:13
-
Is your question really about are there advantages to C over C++? If so then the answer is yes. For the details, either amend your question or ask another (actually this is probably on SO already). – BobbyShaftoe Feb 05 '09 at 23:53
-
I chekced for the similar question but couldn't see before I ask. Actually I was expecting things like litb's answer, but It seems different standarts came out and are being talked. Although I refered the latest versions, it is nice to hear about old ones. – yusuf Feb 06 '09 at 13:07
-
17How about: 'staying sane'? – relet Jul 30 '10 at 13:25
-
11But surely you can't do that in either? – Simon Gill Jul 30 '10 at 13:30
-
12Write code that _compiles_ fast – Emiliano Jul 30 '10 at 14:08
-
1There's different possible meanings. There's no computation you can accomplish in one language but not the other. There are programs that will do one thing in C and something else in C++ (or fail to compile) according to the Standard, although rewriting these is usually trivial. There are things that you can do in almost all common C implementations but not almost all common C++ implementations. – David Thornley Jul 30 '10 at 14:08
-
Nothing of significance. Older versions of C didn't have the level of compile-time type checking that C++ introduced (and later versions of C adopted), so there were some tricks you could do that were clever but not terribly useful beyond inspiring new rules in the IOCCC. – John Bode Jul 30 '10 at 17:24
-
@happy_emi: that's a job for C# :P – Brian S Jul 30 '10 at 18:15
23 Answers
Declare a variable named 'class', as in:
int class = 0;

- 6,837
- 31
- 44
-
9One of the best ways to ensure no one ever compiles your code on a `C++` compiler :D – ereOn Jul 30 '10 at 14:13
-
1Except that you can. The preprocessor is part of the language and there is no clause that you can not redefine a keyword with the pp. – Nordic Mainframe Jul 30 '10 at 14:58
-
3@Luther: true the pp is part of the language specification. Nevertheless, if you use something like `#define class blah` and the above declaration, then your variable is *not* named `class`. It's named `blah`, since everything in the standard, including the names of things, is talking about what happens after macro replacement. Try it for something with external linkage... – Steve Jessop Jul 30 '10 at 15:38
-
1@Luther: Actually, if you include any standard library headers, it is prohibited to define as a macro an identifier that is lexically identical to a keyword. So in any translation unit that includes a standard library header, `#define class blah` is invalid (off the top of my head, I don't know whether it renders the source ill-formed or just results in undefined behavior). – James McNellis Jul 31 '10 at 16:59
-
-
2@Sjoerd: _A translation unit that includes a header shall not contain any macros that define names declared or defined in that header. Nor shall such a translation unit define macros for names lexically identical to keywords_ (C++03 §17.4.3.1.1). Note that "a header" here specifically means "a standard library header." – James McNellis Aug 02 '10 at 21:38
-
@James: Thanks for the quote. It is clearly not allowed to #define class for a small part of our header. My expectation was that it was possible as long as the define would be undone at the point any standard library header was included; I was wrong. – Sjoerd Aug 04 '10 at 08:47
-
This answer is funny, but misses the point (such funny commentary seems better suited as comments than as answers). You can't use "int restrict = 0;" in C99, but you can in C++. Whoopdedo. – Fred Nurk Jan 06 '11 at 11:47
...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.

- 17,697
- 6
- 59
- 114
-
2If possible could you please give any simple program which do run in C and not C++ – i2ijeya Jul 30 '10 at 13:35
-
4http://david.tribble.com/text/cdiffs.htm shows quite a lot of examples of differences. – wilx Jul 30 '10 at 13:42
-
1Many C99 features that aren't in C++ (yet) are already supported by many C++ compilers (especially compilers by vendors that have up to date C99 compilers). – nategoose Jul 30 '10 at 14:48
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];

- 496,577
- 130
- 894
- 1,212
-
What C complier lets you declare varaible length arrays? When I try it, I get "error: expected constant expression" – AShelly Feb 04 '09 at 20:28
-
-
AShelly your compiler does not seem to support the last C standard (C99) in that regard. The feature was added after C++ has been standardized ('98) – Johannes Schaub - litb Feb 04 '09 at 20:37
-
1C99 introduced variable sized arrays. gcc/g++ (4.2.3) supports it. In fact, unless g++ is specifically asked to be strict (-pedantic), it will work in C++ as well. – codelogic Feb 04 '09 at 20:38
-
anyway, the interview asks about C . this is C , and the most recent version of it. statements such as "anything you can do in C you can do in C++." were never true. But since 1999, even less so, of course. – Johannes Schaub - litb Feb 04 '09 at 20:47
-
... and i guess when you come up with differences that include c99, your employer will see you not only know old school, but modern C too. you can still provide it with c89 vs. c++03 difference (no tentative definitions, no default int, no implicit conversion from void* ...) – Johannes Schaub - litb Feb 04 '09 at 20:54
-
This compiler was MSVC++ 2005, using its defaults for .C files. In this particular case (unlike many others), it actually agreeed with my expectations, which boil down to: 'if it's not in K&R 2nd Ed., it's not right'. I admit it - I'm old school. – AShelly Feb 05 '09 at 00:45
-
gcc does not support variable length arrays. They might appear to "work", but they are officially broken. See http://gcc.gnu.org/c99status.html – Chris Young Feb 05 '09 at 09:46
-
It might be worth just adding a note into your answer that you're explicitly referring to C99 and not C90. – Richard Corden Feb 05 '09 at 10:31
-
i purposely don't mention C99 anywhere in my answer. most talk about C99 as a new language compared to C90, when in fact it "cancels and replaces" C90 (quoted from the draft). i will mention it in the answer, if the question is edited to "C90"/"C89" instead of just plain "C" indeed :) – Johannes Schaub - litb Feb 05 '09 at 10:40
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++.

- 63,018
- 25
- 139
- 189

- 43,293
- 10
- 75
- 117
-
1The question was not about the differences but about what C++ can't do what C can. It should be obvious that there are a lot of differences between the two. – Stefan Feb 04 '09 at 20:46
-
Well then I'll rephrase on Darron's behalf: there are many more things which can be done in C but not C++, aside from just using C++ reserved symbols as names. – Steve Jessop Feb 05 '09 at 01:40
-
I undid my edit, which strengthened the concluding assertion; I did not realize that C99 had diverged C from being a subset of C++. – Lawrence Dol Feb 06 '09 at 02:15
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.
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++.
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++.

- 54,973
- 13
- 116
- 224
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."

- 398,270
- 210
- 566
- 880
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.

- 271
- 3
- 3
-
2
-
-
2C does not specify any ABI, but is simple enough that everybody agreed to use the same ABI. Unlike C++. – el.pescado - нет войне Jul 30 '10 at 18:15
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.

- 353,942
- 115
- 666
- 851
-
I can just imagine the chaos if I tried compiling that with G++ lol – figgyfarts Nov 21 '22 at 11:31
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)
forchar 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.

- 46,567
- 13
- 103
- 169
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.

- 34,686
- 15
- 91
- 152
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 */
-
@Matt Havener: This works in C++ too for me! At least on some variants, used clang in xcode. – yairchu Aug 14 '13 at 12:23
-
This feature is called designated initializers and is a cool C99 feature. Trying it with clang, for C++, it compiles but with a warning saying that this is C99 feature not not supported by C++. – Amir Kirsh Jan 19 '23 at 05:39
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

- 35,813
- 6
- 60
- 86
-
4"... although it may be a bit easier in some cases to do it in C due to the lower level of complexity". There. Fixed it for ya'. :) – Dan Moulding Jul 30 '10 at 13:39
-
1
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.

- 18,162
- 2
- 41
- 64
-
"You can do almost everything in any of the programming languages." is good point actually. – yusuf Feb 04 '09 at 20:11
-
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).

- 71,764
- 9
- 59
- 54
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

- 10,489
- 4
- 28
- 62
-
Your comment misses the point but I really liked your link on Bjarn Stroustrup's site, which highlights subtle C/C++ differences in great detail. – Rolf Hendriks Jul 30 '10 at 17:48
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.

- 56,304
- 9
- 91
- 158
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 };

- 3,119
- 19
- 19
- 37

- 15,627
- 7
- 36
- 42
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.

- 311
- 2
- 14
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 thanmain
. - 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 forconst 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. Andvoid
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 typechar
in C++, which saves a tiny bit of memory.

- 195,001
- 40
- 254
- 396
-
Some of the issues are purely theoretical. `restrict` can be replaced with `__restrict`. Union type punning is explicitly allowed at least in GCC manual. – HolyBlackCat Jan 19 '23 at 13:06
"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.

- 11,709
- 17
- 81
- 125
-
Good point. Really the only difference is syntactical. If there were an operational advantage (on top of the existing syntactical advantage) to C over C++ compilers, I'd be extremely interested. – Matt Joiner Jul 30 '10 at 13:40
-
Well, C++ compilers' name mangling is not inter-operable in the way that C compilers' is. Linking multiple C libraries built with different compilers is doable. Linking multiple C++ libraries built with different compilers: not so much. – nmichaels Jul 30 '10 at 14:08
-
I mentioned two operational advantages in my answers - creating portable libraries and writing programs for a platform that only has a C compiler. Though I can't think of a concrete example for the latter. – Rolf Hendriks Aug 13 '10 at 16:00
-
"C++ is functionally a superset of C." It never was. And since this answer was posted, C++ (11 and beyond) has gone completely haywire in relation to C. – Lundin Jan 19 '23 at 14:48
-
@Lundin: Unfortunately, neither the C nor C++ Committee is willing to recognize a principle that should be self-evident: if striking part of the Standard that exists for the purpose of optimization would make it possible to perform via defined means an action that facilitates some tasks, then unless there is some other equally-good way of performing those tasks, that part of the Standard makes the language worse for those tasks than it otherwise would be. Doing that to facilitate optimizing transforms that would be irrelevant for many tasks is a "root-of-all-evil" premature optimization. – supercat Aug 28 '23 at 15:35
The short answer is...no, not really. See http://www.research.att.com/~bs/bs_faq.html#difference

- 16,796
- 4
- 32
- 39