BGB said:
I have not found an answer to the question why C++ is the most preferred
language. I thought it would be a good question to ask in this newsgroup
that has programmers that have been using C++ for a while.
I did read that its popular because it can be transferred to other
platforms but not everyone has more than one platform.
to some extent its momentum, it's popular because it's popular. It's
apparent similarity to C probably has some historical significance. As
others have noted efficiency and access to the underlying machine is
important.
I'm curious, why do you care?
I ask myself why should people program in C++ when Visual Basic is easier
to understand?
I don't find VB easier to understand. It's very verbose and, to me,
the syntax is illogical. But then i've used C++ far more than VB.
yes.
although both C and C++ syntax are still not perfect, they are much
better than VB syntax (which is basically a bit of an ad-hoc mess with
keywords everywhere).
the usual claims to "easier to understand" with very wordy languages has
more to do with the notion that people who are unfamiliar with
programming may assign more semantic meaning to English-like keywords
than to characters on the keyboard.
usually after a short while though, people get used to the characters,
and they no longer are a big issue.
most of the complaining then comes from anti-C-syntax language designers,
who have little better to do apparently than complain about the braces,
semicolons, and the construction of things like the "for()" loop.
the main issues I have found personally (with C-like syntax) are more that:
the traditional declaration syntax is ambiguous;
the traditional C-cast syntax is ambiguous;
...
typically, the parser knows what it is looking at mostly by relying on
prior type declarations (both C and C++), and prior template declarations
(C++), which in-turn makes the issue that header inclusion or some direct
analogue is required for parsing to work correctly, which is a hindrance
to compiler performance (the major example of this is that it often takes
500ms to 1000ms or more to compile something, and much of this is
parsing, mostly churning through the headers).
languages like C# have dealt some with this via a few strategies:
declarations are constrained such that modifiers always precede the
type-name, which is moderately fixed-form, which is followed by the
declaration name (this works, but some more advanced cases will still
introduce ambiguities);
the cast syntax takes precedence and the alternate possible
interpretations (such as applying a computed expression) simply can't be
expressed in the syntax (this means pretty much that any call involving a
delegate has to use a variable, which can then be called, among other limitations).
for example, C# allows:
int *x;
but, at the syntactic level, this can't really be told apart from the expression:
x*y;
their simple answer: disallow the expression case in this case (not a big
issue in C# as statement-level expressions can't produce a meaningful value).
this does, however, allow a much faster parser, but at other costs.
ideally, we want the syntax to be entirely able to be parsed without any
reliance on prior declaration context, and with usually around 1-2 token
lookahead and no back-tracking (context adds need for things like
headers, longer lookahead makes the parser linearly slower, and
backtracking can introduce considerably worse and potentially
polynomial-time slowdowns...).
apart from a few edge cases, most of a C-like syntax can be parsed via a
2-token lookahead and without backtracking. (then we can have parse-times
for a typical-sized module in the microsecond range).
another route is to alter the syntax-design itself to eliminate these
ambiguous cases, for example, using more ECMAScript style declarations.
these have the advantage of being unambiguous at the cost of being longer.
for example:
int x, y;
vs:
var x:int, y:int;
or, potentially:
var:int x, y;
or:
MyObjectType *obj;
vs:
var obj:*MyObjectType;
(actually, moving '*' to precede the type was also related to avoiding a
certain number of ambiguities, some related to constructions which don't
have direct C-ish analogues).
as well as moving casts to an alternate syntax.
for example, in my case, I made it so that all casts use "as" or "as!".
say:
p=(void *)ba;
vs:
p=ba as *void;
this latter case, at least, does not significantly increase the length,
but makes it no longer an issue to be like:
i=(obj[name])(2, 3)(4);
without the parser being confused.
more C++ like casts were possible, but I decided against them mostly as
they are kind of longer and more ugly looking.
granted, yes, such a language isn't really C like.
but, yeah, in my case it was more all motivated by design tradeoffs than
by any dislike of C (and most other areas are much more intact).
many designers are more motivated by personal preferences and "style"
than by pragmatics though, so IMO this may be a large part of what leads
to some of the more bizarre syntax designs seen in some languages.
like "language more meant to be useful" rather than "language meant to
embody some set of ideals" or something like that...
There must be a reason why C++ is chosen when there are many other
languages to chose from.
Maybe some people grow up with C and then moved on to C++ and its close to
what they had used in the past.
True.
You wrote about C++ C and C# of those languages which one do you use to
write programs?
most of my code is C, followed by C++, followed by the language I was
describing (essentially a custom designed script language).
different parts are written in different languages, and it seems fairly
important that they all be able to play along fairly well.
The 'BASIC' language of the late 1970's was very messy and a nightmare to
try and follow the flow of the program unless you wrote very short
programs. VB is a more structured language and because of that it still had
many programmers. But you are right about it being messy as there are many
over sized keywords. So I am currently studying C++ as an alternative to
Visual Basic which I have mainly used in the pass.
yep.
Maybe in the future someone will create a programming language that
everyone's happy with.
could be, but at least in the near-term, not very likely.
very possibly it would require a language which can operate in a number
of modes, for example:
1, a non-hosted C-like mode, where only functionality which can be
implemented directly on the underlying hardware is supported;
2, a hosted C like mode, mostly intended for systems software and libraries;
3, a full-featured natively compiled mode, basically serving a similar
role to C++;
4, a VM managed mode, where it compiles mostly to bytecode images and
these are run (more like the JVM and .NET), which gain CPU portability
at the cost of a much higher increase in the need for support
infrastructure;
5, a dynamically compiled mode, where things are loaded directly from
source and may be compiled from short code-fragments at runtime (more
like languages like JavaScript, Python, Lua, Ruby, PHP, ...).
as-is, there are no languages which effectively cover the entire domain.
C does best in modes 1 and 2 (it can be used in mode 3, but this is
where some people start complaining);
C++ does well in 2 and 3 (and C++/CLI can partly cover 4);
Java is pretty much solely usable in 4;
C# mostly covers 4, but partially covers 5.
mode 5 is mostly off by itself.
ActionScript was more of a mode 4 language. it had descended from
JavaScript, but had lost a lot of mode-5 capabilities (for example, its
"eval" was mostly limited to things like arithmetic expressions and
similar, ...).
C and C++ generally start to show nasty edges in mode 4, and trying to
use C in mode 5 is a bit of a mess (something more like JavaScript is
much more preferable here).
mode 5 benefits greatly from ability to handle fragmentary code and
having very fast compile times, neither of which are natural to C (in
contrast, for statically compiled code, how long the code takes to
compile is much less important, apart maybe from the annoyance of a
programmer waiting many minutes for their program to recompile). in
mode-5 usage, slow compile times can adversely effect application
performance (say, the program takes a big hit whenever anyone calls
"eval()" or similar, worse if they do it in a loop somewhere).
often the tradeoffs differ as well:
modes 1 and 2 generally leave a preference for a "try to handle
everything gracefully and keep things running" approach to error
handling (so, things like error codes are a more common strategy);
modes 3 and 4 generally leave a strong preference for a "die fast and
die hard" strategy for error handling (the assumption is that a critical
problem often represents something going wrong in the application, which
needs to be fixed);
mode 5 generally prefers a much "softer" approach to error handling,
typically giving debugging messages and trying to make things no-op
(consider just how annoying it would be, say, if FireFox died hard every
time there was a buggy piece of JS code on a website?...).
in my game project, the code breakdown is more like:
1: not used (usually we only see this in OS kernel/driver code and
things like the C runtime);
2: generally plain C;
3: generally tooled-up C, and some C++;
4&5: my script language (BGBScript), previously some Java was used, but
BS has largely replaced it (design-wise, BS is largely a mode-5
language, which has expanded some into mode-4 territory).
currently, I don't have a C compiler for the bytecode VM (would be mode
4), nor a native compiler for BS (to allow mode 3).
the C FFI is designed mostly to allow easy interfacing in these
configurations:
mode-3 C <-> mode-4 BS;
mode-5 BS -> mode-3 C.
(it is hard to effectively handle calls from statically-compiled C code
to BS code which was probably compiled via an "eval" call or similar, so
this generally isn't done, but it is much easier to allow easy calls
from C into statically-compiled VM images, since in this case both exist
with a discrete "compile time", it is possible to spit out some
trampolines and similar to bridge the languages).
BS will have a harder time with "plain C", mostly in the sense that C
code which isn't using a lot of the VM runtime facilities, will
generally be much less friendly to any non-C code, and will generally be
harder for script code to work with.
as-is, it is not clear how a single language can handle all of these
cases without introducing a number of ugly seams (code intended for one
use-domain potentially looking wildly different from code intended for
another use domain).
say, code written to run in an OS kernel being almost unrecognizably the
same language as the code intended to run in high-level scripts.