Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


why is C++ not commonly used in low level code?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • This topic is locked This topic is locked
70 replies to this topic

#41 Conoktra   Members   -  Reputation: 140

Posted 18 July 2011 - 07:10 PM

With regards to Linus Torvalds and Linux:
  • C is used in Linux because of its versatility. It can do everything C++ can do, but also gives you fined-tuned control over every aspect of program at the cost of expertise. This "theme" is the very core of Linux--to have a OS that is extremely versatile, but often times harder to run without the expertise (which is why the two work hand-in-hand). Here is a quick example of this:
  • In C++ it has built-in OO functionality via classes. This makes things such as polymorphism much easier. BUT, by using classes you loose control of how object pointers are handled in the member functions, you loose control of how constructors/destructors are called and when, how member-function pointers are stored within the structure, etc etc.
  • In C you can still do OO programming just like C++ classes by using structures and callbacks via function pointers. But, you get the ultimate control of how everything happens. YOU decide when constructors/destructors are called, YOU decide how object pointers are passed to member-functions, and YOU decide how member function pointers are stored in the structure and how they are alligned.
  • By having this fine-control in C it allows you to write extremely fast and efficient code, while still doing everything C++ does. Here are a couple of examples:
  • I could choose a special alignment of the function pointers that could produce huge performance boosts on certain systems.
  • I could choose to pass the object pointer to the member function via the stack instead of a register, thus saving the register for a different parameter--which when used right, could provide huge performance boosts.
  • Etc etc.
[*]C is typically more compatible with other programming languages(particularly that of scripted languages)--which makes creating wrappers much easier (scripted languages is a huge part of Linux).[*]Although C++ isn't inherently a bad/inefficient language, the concepts it introduces often times leads to poor code. Because Linux is open-source and has thousands of contributors, having perfect, well-written code is a must. Here is a quick example:
  • In C++ I am writing a bubble-sorting algorithm to sort a list of strings alphabetically. In C++ the quick'n'easy solution would be to store the strings as a std::string, and store the group of strings as a std::vector. Once sorting, each time I swap two strings a total of 10 things happen: A) a extra std::string constructor is called, and B) 3 memory-free operations, and C) 3 memory-alloc operations, and 3 memory-copy operations. If each string is 10,000 characters in size, and there are 40,000 strings your looking at a huge overhead implementing it this way.
  • In C, one would simply allocate an array of 40,000 char ** pointers, then alloc each pointer with a pointer to 10,000 characters each. An extra 10,000 character buffer would be needed for the swapping stage. Now, once sorting, 3 things would happen to swap two strings: a total of 3 memory-copy operations. This is much simpler, and scores faster in nature than the obvious C++ implementation. In addition, because you have direct access to the char ** and char * pointers you can modify their alignment, as well as using the registers to store the generic pointers, in order to achieve additional performance boosts.
  • Additionally, by using std::string and std::vector you import a gargantuan hunk of code to your project. If executable size, compile-time, or load-time are a concern than C is definitely the winner.
[/list]I am not bashing on C++, I know a lot of people like it. For me, and obviously Linus + Linux, C is the way to go :). Its really just a matter of opinion.

Sponsor:

#42 Calmatory   Members   -  Reputation: 116

Posted 18 July 2011 - 08:31 PM

2 points;

1) std::cin and std::cout are doing more than the scanf and printf under the hood, which are both valid C++ functions btw and thus any coder worth their salt would use them if the situation required it*
2) As soon as the input string exceeds 32 characters your C code runs the risk of blowing up nicely; the C++ version is safe in that regard.

(* it becomes a speed vs safety trade off... if you want speed then you'd take the functions with the lowest overhead, if you want safey then you have to ditch some of that speed)


You are right, and I did this on purpose. As I mentioned before, with C++ I mean as "pure" C++ as it gets. It's no use to exploit as much C feature-set with C++ code and go all "But this IS valid C++ too!". There's no way to define when to stick to C library or when to use the C++ equivalents. Though, my main point for C is still it's portability(well supported on numerous platforms) and simplicity(Not so hard to write/port a custom compiler for custom hardware).





Since people have been critical towards the example I gave, I challenge others to write example code too for us all to learn more from.



#43 Hodgman   Moderators   -  Reputation: 30930

Posted 18 July 2011 - 09:27 PM


  • C is used in Linux because of its versatility. It can do everything C++ can do, but also gives you fined-tuned control over every aspect of program at the cost of expertise. This "theme" is the very core of Linux--to have a OS that is extremely versatile, but often times harder to run without the expertise (which is why the two work hand-in-hand). Here is a quick example of this:
  • In C++ it has built-in OO functionality via classes. This makes things such as polymorphism much easier. BUT, by using classes you loose control of how object pointers are handled in the member functions, you loose control of how constructors/destructors are called and when, how member-function pointers are stored within the structure, etc etc.
  • In C you can still do OO programming just like C++ classes by using structures and callbacks via function pointers. But, you get the ultimate control of how everything happens. YOU decide when constructors/destructors are called, YOU decide how object pointers are passed to member-functions, and YOU decide how member function pointers are stored in the structure and how they are alligned.
  • By having this fine-control in C it allows you to write extremely fast and efficient code, while still doing everything C++ does. Here are a couple of examples:
  • I could choose a special alignment of the function pointers that could produce huge performance boosts on certain systems.
  • I could choose to pass the object pointer to the member function via the stack instead of a register, thus saving the register for a different parameter--which when used right, could provide huge performance boosts.
  • Etc etc.

I know that you know that you can do all of that in C++ as well as in C....[/list]So... all this really means is that a shit C++ programmer is worse than a good C programmer?
Shit is worse than good?
Ok.

You are right, and I did this [wrote an invalid benchmark] on purpose. As I mentioned before, with C++ I mean as "pure" C++ as it gets.

You're just demonstrating that you don't know C++ very well then, as instead of using a heavyweight formatted and localized output stream, you could've used a lightweight one that was a better analog of
printf... Or if the task really needed printf, a good C++ programmer might just use printf.

It's no use to exploit as much C feature-set with C++ code and go all "But this IS valid C++ too!".

Why?

We use C++ for a ton of low-level stuff at work, most of it without the use of virtual, etc...
It's very "C-like" in style, but we've got a few extra tools to play with as well.
e.g. you said before that in C++ you give up control over when constructors/destructors are called, but in some very low-level code, we use placement-new (new (preAllocatedBuffer) T()) and explicit destructor calls (p->~T()) to do exactly that. A lot of our low-level code does take the reigns and make explicit decisions about all the things you say that you're giving up in C++.
Again, your idea of what "typical C++" is, is not at all what good C++ programmers write, and yes, it is C++, not C.

You really are just saying that shit C++ is worse than good C code... or that because you've got extra tools in your tool-box, you're somehow forced to use them for every problem? What's wrong with having a few extra tools that you only pull out occasionally?

#44 ApochPiQ   Moderators   -  Reputation: 15997

Posted 18 July 2011 - 09:30 PM

C is used in Linux because of its versatility. It can do everything C++ can do, but also gives you fined-tuned control over every aspect of program at the cost of expertise.


Brainfuck can do everything C can do, but also gives you fine-tuned control over every atomic instruction of your program at the cost of expertise. So why isn't Linux written in Brainfuck?

Because your argument is fallacious. C does not do everything C++ does, in the sense that C does not provide black-box abstractions that C++ provides. This means that C is fundamentally a less productive language when comparing the efficiency of experts in either language.

In C++ it has built-in OO functionality via classes. This makes things such as polymorphism much easier. BUT, by using classes you loose control of how object pointers are handled in the member functions, you loose control of how constructors/destructors are called and when, how member-function pointers are stored within the structure, etc etc.


Bullshit.

Object pointers are always passed using thiscall, i.e. in the first (hidden) parameter to the function. This is not magic and does not remove anything. In fact, you can write a shim that translates from arbitrary C-style pointer passing to thiscall in three lines of code:

int InvokeFoo(int argument1, int argument2, Foo* ptr)
{
	ptr->FooImpl(argument1, argument2);
}

Construction and destruction are performed in very, very well defined ways and in well defined orders. I suspect you don't know C++ very well if you aren't aware of how to reason about construction and destruction order in a program. For stack-allocated objects it's bloody trivial; for free-store-allocated objects, it's only slightly more complex due to the presence of placement new and explicit destructor invocation. But those things give you perfect control over construction and destruction patterns, not remove control.

Your last "argument" is nonsensical. My best guess is that this is some oblique reference to the vtable, which is hardly something you need to tamper with... well, ever, really, in a proper C++ program. And guess what? If you're psycho and really want to write your own vtable, C++ has member function pointer syntax which lets you do so, while retaining thiscall semantics.

So there is absolutely no loss of control here - you just personally don't know how to obtain that control, apparently.

In C you can still do OO programming just like C++ classes by using structures and callbacks via function pointers. But, you get the ultimate control of how everything happens. YOU decide when constructors/destructors are called, YOU decide how object pointers are passed to member-functions, and YOU decide how member function pointers are stored in the structure and how they are alligned.


I control all of that in C++ too. And, what's better, I don't have to think about it 99% of the time, because the language makes certain default guarantees that accommodate the vast majority of use cases with no issue.

And, guess what, I can still control all of that by hand if I really want to.

I could choose a special alignment of the function pointers that could produce huge performance boosts on certain systems.


AFAIK any decent C++ compiler will native-align the vtable entries; in fact, they'd almost have to bend over backwards not to, because vtable entries are by definition machine pointer size to begin with. So I don't think you really know what you're comparing with here.

I could choose to pass the object pointer to the member function via the stack instead of a register, thus saving the register for a different parameter--which when used right, could provide huge performance boosts.


You can implement your own calling convention on top of thiscall trivially in C++, if you know what you're doing. (Compiler specific, of course.)

In C++ I am writing a bubble-sorting algorithm to sort a list of strings alphabetically. In C++ the quick'n'easy solution would be to store the strings as a std::string, and store the group of strings as a std::vector. Once sorting, each time I swap two strings a total of 10 things happen: A) a extra std::string constructor is called, and B) 3 memory-free operations, and C) 3 memory-alloc operations, and 3 memory-copy operations. If each string is 10,000 characters in size, and there are 40,000 strings your looking at a huge overhead implementing it this way.


Or you could use std::string::swap like any first-year C++ student would know to do, and your C++ program boils down to the C program with extra type safety and memory management safety.


The vast majority of people who argue against C++ are not arguing against the language itself, but rather against people who don't know how to use the language. Granted, crappy C++ "programmers" are a dime a dozen, so caveat emptor - but there's no really good argument for C over C++ that actually has to do with the languages themselves. It's all down to comparing tools, relying on history, selecting for certain types of programmers, or bigotry.

#45 Calmatory   Members   -  Reputation: 116

Posted 18 July 2011 - 09:45 PM

You really are just saying that shit C++ is worse than good C code... or that because you've got extra tools in your tool-box, you're somehow forced to use them for every problem? What's wrong with having a few extra tools that you only pull out occasionally?

So what would your conclusion be for both C and C++? A right tool for the right task? What tasks are right for C but not C++? What tasks are right for C++ and not C?

I'm still waiting for better code examples. Indeed, I am a shit C++ programmer, which doesn't take away the fact that C++ is bloaty when compared to C(yes, I provoke on purpose. Prove me wrong :P). And this is one of the reasons why C is preferred over C++ in many low level tasks.




#46 Yann L   Moderators   -  Reputation: 1798

Posted 18 July 2011 - 10:21 PM

Indeed, I am a shit C++ programmer

And that is exactly the problem. How can you make statements about a language you admittedly have low expertise in ? The "benchmark" example you provided earlier is the perfect example of that. You were comparing two pieces of code that had nothing at all in common except for outputing text. That text editor written in C is faster than that protein-folding simulator written in C++. Obviously this must mean that C is better...

In fact this is something one can observe in almost all C vs C++ discussions. The most rabid C defenders (explicitly including Linus Torvalds) have actually very little knowledge of C++, sometimes leading to almost absurd arguments.

which doesn't take away the fact that C++ is bloaty when compared to C(yes, I provoke on purpose. Prove me wrong :P)

Prove yourself wrong by learning C++ before making factually incorrect statements about it. Counter arguments to your points are trivial common knowledge to every semi-competent C++ programmer.

#47 Calmatory   Members   -  Reputation: 116

Posted 18 July 2011 - 11:00 PM

I did not base my judgment solely on the code I provided and it's size, but also on my past experience with it for writing small code(binary size sub 1024/4096 bytes) and the common practices in demoscene. Instead of ranting, teach me. Show me. I'm asking for fourth time for someone to show how things are done correctly, and I'd appreciate it if it actually showed that C++ would be more ideal for low-level development than C. Especially for embedded systems in which resources are scarce.




I'm waiting for code.



#48 KanonBaum   Members   -  Reputation: 277

Posted 18 July 2011 - 11:07 PM

Posted Image

*Note: I code in C++. I just thought I'd share the laughs.
I'm that imaginary number in the parabola of life.

#49 Hodgman   Moderators   -  Reputation: 30930

Posted 18 July 2011 - 11:33 PM

So what would your conclusion be for both C and C++? A right tool for the right task? What tasks are right for C but not C++? What tasks are right for C++ and not C?

IMHO, C is the right choice if:
* you've got a team who are good C programmers but bad at C++, and you don't trust them to not write bad C++ code (pitfalls of OOP is a good example of the performance disaster that bad C++ can lead to).
* you're on a platform with a good C compiler but a bad C++ compiler.
* you really want to use some C99 feature that isn't supported in your C++ compiler for some reason.

Instead of ranting, teach me. Show me. I'm asking for fourth time for someone to show how things are done correctly, and I'd appreciate it if it actually showed that C++ would be more ideal for low-level development than C. Especially for embedded systems in which resources are scarce. I'm waiting for code.

I'm not going to fix your hello-world printf vs cout loop, because it's just a hello-world problem and has no relation to any real problems. Does anyone even use cout, in anything but "hello world"? Posted Image

I'm too busy writing high-performance C++ for embedded devices to tutor you right now, but the folks at Dice have some presentations on how to not write bad C++ that you should absolutely read: http://publications....ory=Engineering. The 'Scope Stack Allocation' presentation is a particularly good gem.
You'll be happy to see that the result is very "C style" Posted Image

#50 Calmatory   Members   -  Reputation: 116

Posted 19 July 2011 - 12:34 AM

Indeed, the presentations are real gems! Thanks for them, very interesting. I guess it's needless to say at this point that to make the most out of C++, it has to be very C-like, perhaps even relying on the C library rather than the C++ one?

#51 ChaosEngine   Crossbones+   -  Reputation: 2435

Posted 19 July 2011 - 12:55 AM


So what would your conclusion be for both C and C++? A right tool for the right task? What tasks are right for C but not C++? What tasks are right for C++ and not C?

IMHO, C is the right choice if:
* you've got a team who are good C programmers but bad at C++, and you don't trust them to not write bad C++ code (pitfalls of OOP is a good example of the performance disaster that bad C++ can lead to).
* you're on a platform with a good C compiler but a bad C++ compiler.
* you really want to use some C99 feature that isn't supported in your C++ compiler for some reason.

Instead of ranting, teach me. Show me. I'm asking for fourth time for someone to show how things are done correctly, and I'd appreciate it if it actually showed that C++ would be more ideal for low-level development than C. Especially for embedded systems in which resources are scarce. I'm waiting for code.

I'm not going to fix your hello-world printf vs cout loop, because it's just a hello-world problem and has no relation to any real problems. Does anyone even use cout, in anything but "hello world"? Posted Image

I'm too busy writing high-performance C++ for embedded devices to tutor you right now, but the folks at Dice have some presentations on how to not write bad C++ that you should absolutely read: http://publications....ory=Engineering. The 'Scope Stack Allocation' presentation is a particularly good gem.
You'll be happy to see that the result is very "C style" Posted Image


Ironically, their latest presentation is essentially "don't use C++ features" :D
http://www.slideshare.net/DICEStudio/executable-bloat-how-it-happens-and-how-we-can-ght-it
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

#52 Aardvajk   Crossbones+   -  Reputation: 6055

Posted 19 July 2011 - 02:58 AM

I guess it's needless to say at this point that to make the most out of C++, it has to be very C-like, perhaps even relying on the C library rather than the C++ one?


Sure. All the hundreds of thousands of dollars spent funding research and development, ratifying standards and building compilers was just to be awkward. Obviously none of it was ever intended to be used in production code. [/sarcasm]

The facts are these: the domain we are discussing in this thread, very low level code written to execute with a very small memory footprint and realistically valid concerns about micro-optimisation, is highly specialised and represents a tiny, tiny subset of programming domains in general.

The point, as it seems to me, is that C++ is suitable for both this domain, and a variety of other domains including complex application development where the additional features of C++ come into their own. C is suitable for a far lesser variety of domains.

You seem to have a skewed idea of what C++ is to be honest. print() is a C++ standard library function. Function pointers are a C++ language feature. The fact that C++ happens to have these in common with C does not make using them in C++ writing a "C-like" program, any more than using a regular expression library makes my C++ "grep-like".

C++ provides the efficiency of C when required and a host of useful features on top that are normally implemented by the compiler far more cheaply than paying a C programmer to write the equivalent functionality manually. The fact that there are fewer programmers expert enough to use these features effectively, as per Mr T's spurious and silly arguments, is cultural, historical and has nothing whatsoever to do with the language.

You are not advocating against using a sledgehammer to crack a walnut. You are advocating against owning a toolbox with a variety of tools, including a walnut cracker, over simply owning a walnut cracker. (Sits in corner and waits for analogy police to arrive).

#53 Calmatory   Members   -  Reputation: 116

Posted 19 July 2011 - 03:23 AM


I guess it's needless to say at this point that to make the most out of C++, it has to be very C-like, perhaps even relying on the C library rather than the C++ one?


Sure. All the hundreds of thousands of dollars spent funding research and development, ratifying standards and building compilers was just to be awkward. Obviously none of it was ever intended to be used in production code. [/sarcasm]

The facts are these: the domain we are discussing in this thread, very low level code written to execute with a very small memory footprint and realistically valid concerns about micro-optimisation, is highly specialised and represents a tiny, tiny subset of programming domains in general.


Sigh.. ...but what if this topic explicitly covers just that tiny subset of programming domains in general? :)










#54 Aardvajk   Crossbones+   -  Reputation: 6055

Posted 19 July 2011 - 03:32 AM

Sigh.. ...but what if this topic explicitly covers just that tiny subset of programming domains in general? :)


Then I refer to the point that C++ is suitable for these subsets while providing improved type-safety and generics at no extra cost, except for programmer training.

I have no interest in arguing that X is better than Y. I am, however, happy to argue that a box of tools is better than a tool on its own. If I want my lawn cut, I'd rather employ a gardener who also owns a chainsaw just in case I suddenly decide a tree needs pruning while he is there. If not, his chainsaw can stay in the van.

Plus, to stretch the analogy to beyond breaking point, his lawnmower is less likely to electrocute my cat.

#55 Calmatory   Members   -  Reputation: 116

Posted 19 July 2011 - 03:46 AM

But if C++ is suitable, and better by providing improved type-safety and generics at no extra cost, why isn't C++ used instead of C? That's the fundamental question behind this whole topic. :)




And not to repeat myself, but I believe it is because 1) C is more compact in terms of resource usage. 2) C is more portable, so there are more mature compilers for wider variety of platforms 3) C is simpler, easier to learn and use properly and there exists lots of good enough programmers for the job.



#56 SymLinked   Members   -  Reputation: 879

Posted 19 July 2011 - 03:49 AM

Sigh.. ...but what if this topic explicitly covers just that tiny subset of programming domains in general? :)


Sigh all you want. With the same immature reasoning I could say that using ASM in C makes C less of a usable language because in some cases it was worthwhile to write inlined ASM to write performant C code. Look at the Linux kernel? You can use Google and a brain to find it.

Your broken code example was entertaining, though. :rolleyes:

#57 Calmatory   Members   -  Reputation: 116

Posted 19 July 2011 - 04:06 AM


Sigh.. ...but what if this topic explicitly covers just that tiny subset of programming domains in general? :)


Sigh all you want. With the same immature reasoning I could say that using ASM in C makes C less of a usable language because in some cases it was worthwhile to write inlined ASM to write performant C code. Look at the Linux kernel? You can use Google and a brain to find it.

Your broken code example was entertaining, though. :rolleyes:


Instead of ranting you could debunk the three points I made in my earlier post, after you realize that this topic is indeed about low-level programming and I am myself talking mainly about embedded(especially non-x86) systems.

The difference between native code(asm) and C is far greater than the difference between C and C++, and as you probably knew this, it makes me wonder why you had to bring it up in the first place?

#58 Aardvajk   Crossbones+   -  Reputation: 6055

Posted 19 July 2011 - 04:07 AM

1) C is more compact in terms of resource usage.


Disagree, as stated.

2) C is more portable, so there are more mature compilers for wider variety of platforms


Agree, as stated, with reservations. Age and ease of implementation are the reasons, not portability. C++ has a perfectly well-defined standard.

3) C is simpler, easier to learn and use properly and there exists lots of good enough programmers for the job.


Agree, as stated, with reservations. "Properly" is a dangerous term. Your own example with the potentially breaking limitation of a 32 character name well demonstrates this point.

#59 rip-off   Moderators   -  Reputation: 8515

Posted 19 July 2011 - 04:16 AM

In C++ I am writing a bubble-sorting algorithm to sort a list of strings alphabetically ... If each string is 10,000 characters in size, and there are 40,000 strings your looking at a huge overhead implementing it this way.

If there are 40,000 strings, why have you decided to bubble sort them? This is under a bullet point talking about efficiency.

#60 Hodgman   Moderators   -  Reputation: 30930

Posted 19 July 2011 - 04:29 AM

But if C++ is suitable, and better by providing improved type-safety and generics at no extra cost, why isn't C++ used instead of C? That's the fundamental question behind this whole topic. :)

It is...Posted Image
C++ is used instead of C, commonly, in low-level code.

The question behind the topic is based on a false assumption.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS