C/C++ guidelines

C

Charlie Gordon

Chris Thomasson said:
[...]
#include <stdlib.h>
#define alloc_type(type) ((type*)malloc(sizeof(type)))
#define alloc_array(type,n) ((type*)malloc((n) * sizeof(type)))

char *p = alloc_array(char, 100);
int *p = alloc_array(int, 100);
float *p = alloc_array(int, 100); // constraint violation

Why not calloc?

That would be a sensible choice. Had I made it, one would have asked why
waste time initializing the array ?

As a matter of fact, it tends to be more useful to initialize the block to
all 0, and have another macro alloc_array_raw() for the rare cases where
initialization is both useless, costly and wasteful.

To be complete, we also have to account for the rare if at all existent, but
still Standard supported architectures where all bits 0 initialization is
inappropriate for pointers, floats or doubles.
 
D

Default User

Richard said:
CBFalconer said:


Clearly you are not a fan of Terry Pratchett's "Discworld" novels, in
which one of the principal characters has "wizzard" emblazoned on his
pointy hat. (Not only can the character not spell, but he can't spell
either.)


As you know Bob, that's where the "out of cheese" error comes from as
well. The ant-based computer "Hex" has a mouse component as well.




Brian
 
K

Keith Thompson

Charlie Gordon said:
"Keith Thompson" <[email protected]> a écrit dans le message de
(e-mail address removed)... [...]
I agree completely *if* we're just talking about C (as we normally do
here). But the original article in this thread asserted a requirement
to compile the same code as C and as C++. Assuming such a
requirement, using a macro to hide the ugly cast from C programmers
and the ugly use of malloc() from C++ programmers makes some sense.

These macros, along with corresponding free_type and free_array could be
implemented differently for the C++ target, using new and delete.
Hiding the gory details does help ;-)

Note that there's a semantic difference between using malloc/free and
using new/delete. They can't be mixed, and new/delete provide no
equivalent of realloc.

But if you have the discipline to use the macros consistently and
never invoke *alloc, free, new, or delete directly, and you don't need
the functionality of realloc, this isn't a problem.
 
C

CBFalconer

Charlie said:
"CBFalconer" <[email protected]> a écrit:
.... snip ...


Of course, but keep in mind the OP's question: he wants his code
to compile and function the same as both C and C++ code. Your
proposal does fit that goal. While your code is very elegant, it
cannot be used for void *p.

Which brings up something I don't know and am not willing to dig
out (because I will never use it). With void *p above, what does
"sizeof *p" return. If, as I suspect, it is zero, then everything
works accurately. However dereferencing that storage may lead to
future problems. :)

BTW, it's not "my code" that is elegant, it is this newsgroups and
general good practice.
 
K

Keith Thompson

CBFalconer said:
Which brings up something I don't know and am not willing to dig
out (because I will never use it). With void *p above, what does
"sizeof *p" return. If, as I suspect, it is zero, then everything
works accurately. However dereferencing that storage may lead to
future problems. :)
[...]

'sizeof *p', like 'sizeof(void)', is a constraint violation.
C99 6.5.3.4p1:

The sizeof operator shall not be applied to an expression that has
function type or an incomplete type, to the parenthesized name of
such a type, or to an expression that designates a bit-field
member.

<OT> gcc yields 1 for both expressions, as part of its extension to
allow pointer arithmetic on void*. IMHO this extension was a bad
idea. gcc warns about this when invoked with the right options. </OT>
 
T

Tor Rustad

[...]
#ifndef __STDC__
#warning "Non Standard C compiler used"
#endif

You also need to check for __STDC__ being defined as something other
than 1. Some compilers have used __STDC__==0 to indicate partial
compliance.

*red face*

Furthermore, #warning isn't even standard C.
 
V

Victor Bazarov

Tor said:
[...]
#ifndef __STDC__
#warning "Non Standard C compiler used"
#endif

You also need to check for __STDC__ being defined as something other
than 1. Some compilers have used __STDC__==0 to indicate partial
compliance.

*red face*

Furthermore, #warning isn't even standard C.

But would the fact that __STDC__ is not defined be reason enough to
use non-standard directive? :) I mean, shouldn't the preprocessor
just skip anything it sees between #if 0 and #endif?


V
 
T

Tor Rustad

Victor said:
But would the fact that __STDC__ is not defined be reason enough to
use non-standard directive? :) I mean, shouldn't the preprocessor
just skip anything it sees between #if 0 and #endif?

Introducing constructs outside the common subset of C and C++, isn't
exactly what OP asked for.

My idea was to replace the #error directive, with something that would
allow the code to compile in more cases, including under a C++ compiler.
 
R

Richard Bos

Karl Heinze said:
Actually, I already found that habit (casting malloc's return value)
described as _good coding practice_.

Which it isn't. It is, in fact, bad practice. It is necessary in C++
because that language's type safety system is fubar, but there is very
little dangerous or unusual about assigning a void * to another object
pointer, as long as you pay even a minimum of attention to what you're
doing where; and (for fairly obvious reasons) doing so to the void * you
just got from malloc() carries not the very least of danger and is very
common.
Putting a cast on a malloc() call is like hanging a high voltage sign on
an AA battery cell. C++'s requirement that it be done is like a law
demanding that batteries carry high voltage warnings. Both actually
increase the danger in those cases where there really _is_ an unusual
situation, to which the warning would have drawn attention had it not
been for the plethora of useless warning signs.

Richard
 
J

John Bode

Hi groups,

I'm about to embark on a new project and for maximum portability we've
been asked to code it in the common subset of C and C++.

That's a nonsensical request. Seriously. How is a (potentially
crippling) subset of C and C++ any more *portable* than straight C or C
++? It's like asking someone to code in the common subset of Ada and
Pascal. Just because the intersection between C and C++ is usably
larger doesn't make it any more sane to do.

Is this code going to be compiled as both C and C++? If so, why?
What's the driver for that? What's the perceived benefit? If all
you've been given is some mumblage about "portability", ask the
dipstick who's telling you to do this to provide you with solid
numbers showing greater support across platforms for the subset as
opposed to straight C or C++; otherwise he's just making shit up and
setting you up for failure.

If you honestly need C++ features (classes, templates, STL, etc.),
then write C++. If you don't, then write C. It's perfectly okay to
have a project that consists of both C and C++ files, you just have to
structure your builds appropriately and pay attention to linkage
rules. But for the love of God, don't try to mix the two in the same
source file. That way lies nothing but heartburn.
Can anyone suggest any good documents that might help us? Lists of
gotchas to avoid, that sort of thing?

As others have mentioned, avoid using C++ reserved words as
identifiers (namespace, new, delete, etc.). Realize that the
declaration

int f();

means different things to C and C++ (in C++, f is understood to take
no parameters, whereas in C, f is understood to take an unspecified
number of parameters).

Harbison & Steele's "C: A Reference Manual", 5th ed., has a section on
C++ compatibility in just about every chapter. You might find that
useful.

But again, it's really better to write in C *or* C++, not a crippled
subset of the two.
 
C

CBFalconer

John said:
That's a nonsensical request. Seriously. How is a (potentially
crippling) subset of C and C++ any more *portable* than straight
C or C++? It's like asking someone to code in the common subset
of Ada and Pascal. Just because the intersection between C and
C++ is usably larger doesn't make it any more sane to do.

Is this code going to be compiled as both C and C++? If so, why?
What's the driver for that? What's the perceived benefit? If
all you've been given is some mumblage about "portability", ask
the dipstick who's telling you to do this to provide you with
solid numbers showing greater support across platforms for the
subset as opposed to straight C or C++; otherwise he's just
making shit up and setting you up for failure.

In other words you are advising Robbie, who appears to be a
relative newbie, to get into a knock-down fight with his boss,
attempt to oust and replace him, using his superior knowledge and
attitude as an absolute weapon. Pah. Foo.

Advising him of the facts is one thing. How to achieve the
objective is not up to you. My own opinion is that use of suitable
facts will eventually suffice, and that a war will gain nobody
anything (except the door).
 
K

Keith Thompson

John Bode said:
As others have mentioned, avoid using C++ reserved words as
identifiers (namespace, new, delete, etc.). Realize that the
declaration

int f();

means different things to C and C++ (in C++, f is understood to take
no parameters, whereas in C, f is understood to take an unspecified
number of parameters).

'int f();' is the preferred way in C++ to indicate that f takes no
arguments, but 'int f(void);' is also valid. If you *must* write
code that's valid C and valid C++, you can use 'int f(void);'.

[...]
But again, it's really better to write in C *or* C++, not a crippled
subset of the two.

Agreed.
 
A

Alf P. Steinbach

* CBFalconer:
In other words you are advising Robbie, who appears to be a
relative newbie, to get into a knock-down fight with his boss,
attempt to oust and replace him, using his superior knowledge and
attitude as an absolute weapon. Pah. Foo.

Advising him of the facts is one thing. How to achieve the
objective is not up to you. My own opinion is that use of suitable
facts will eventually suffice, and that a war will gain nobody
anything (except the door).

Well, I adviced the same earlier in this thread, but, thinking about it...

In my experience a boss who intervenes in technical decisions and orders
something technically hare-brained, will not react kindly to facts,
except he may continue to act pleasantly. He (it is inevitably a he)
will /make/ it into a war. And the original technically hare-brained
order was probably very calculated and politically astute.

So I retract my earlier advice. Best advice is probably to quit.

Cheers,

- Alf
 
B

Bo Persson

CBFalconer wrote:
:: John Bode wrote:
:::
:::: I'm about to embark on a new project and for maximum portability
:::: we've been asked to code it in the common subset of C and C++.
:::
::: That's a nonsensical request. Seriously. How is a (potentially
::: crippling) subset of C and C++ any more *portable* than straight
::: C or C++? It's like asking someone to code in the common subset
::: of Ada and Pascal. Just because the intersection between C and
::: C++ is usably larger doesn't make it any more sane to do.
:::
::: Is this code going to be compiled as both C and C++? If so, why?
::: What's the driver for that? What's the perceived benefit? If
::: all you've been given is some mumblage about "portability", ask
::: the dipstick who's telling you to do this to provide you with
::: solid numbers showing greater support across platforms for the
::: subset as opposed to straight C or C++; otherwise he's just
::: making shit up and setting you up for failure.
::
:: In other words you are advising Robbie, who appears to be a
:: relative newbie, to get into a knock-down fight with his boss,
:: attempt to oust and replace him, using his superior knowledge and
:: attitude as an absolute weapon. Pah. Foo.
::

I think he is saying that if your boss doesn't have a clue about the
work you are supposed to do, it's time to get yourself a new boss. One
way or another.


Bo Persson
 
W

Willem

Alf wrote:
) In my experience a boss who intervenes in technical decisions and orders
) something technically hare-brained, will not react kindly to facts,
) except he may continue to act pleasantly. He (it is inevitably a he)
) will /make/ it into a war. And the original technically hare-brained
) order was probably very calculated and politically astute.

I'm not quite sure I follow you. Do you mean the original order has always
been very calculated, or do you mean that it retroactively becomes so ?

And, in the first case, what would be a good example of why a hare-brained
technical decision would be so calculated, politically ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

John Bode

In other words you are advising Robbie, who appears to be a
relative newbie, to get into a knock-down fight with his boss,
attempt to oust and replace him, using his superior knowledge and
attitude as an absolute weapon. Pah. Foo.

I am advising Robbie to make sure that the person imposing this
requirement really understands what it is they are asking, because it
will lead to a suboptimal solution. Whether that involves a knock-
down fight or a simple, "Hey, boss, are you sure using a subset of C
and C++ is really more *portable* than just straight C, because I've
heard differently, and I was just wondering where you got your
information," is up to Robbie.

I only rant because I've seen too many instances of people imposing
stupid requirements because it "should be" faster/easier/portabler
without actually taking the effort to figure out if it really *is*
faster/easier/portabler.
 
A

Alf P. Steinbach

* Willem:
Alf wrote:
) In my experience a boss who intervenes in technical decisions and orders
) something technically hare-brained, will not react kindly to facts,
) except he may continue to act pleasantly. He (it is inevitably a he)
) will /make/ it into a war. And the original technically hare-brained
) order was probably very calculated and politically astute.

I'm not quite sure I follow you. Do you mean the original order has always
been very calculated, or do you mean that it retroactively becomes so ?

And, in the first case, what would be a good example of why a hare-brained
technical decision would be so calculated, politically ?

The original, not retroactively, i.e. first case.

Mainly ordering someone to do something in a technically hare-brained
but not completely infeasible way is IME a political tool, which can be
used to (1) pass on blame for something else, (2) establish dominance
(perkelee management), and/or (3) get rid of or put someone down a few
notches, e.g. if that someone has an irritating habit of being honest.

In this case it's a new project. It may sound absurd that the project's
manager is actively trying to make the project fail or go over budget
and time, yet apparently that seems to be what he does (I'm guessing
"he"). And one actual experience I can relate that to was a project
that the manager had been manouvered into taking on, an "impossible"
project, an Urias assignment, where he needed to be able to pass the
blame for failure in a way that was not obvious to other managers.

Cheers,

- Alf (engaging in off-topic and cross-posting, hey hey!)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top