From: Keith Thompson on
John Bode <jfbode1029(a)gmail.com> writes:
[...]
> The all-caps convention makes it easier to distinguish preprocessor
> macros from other symbols. This can matter, especially when using
> function-like macros (macros that take arguments). Remember that
> macro expansions are simple text substitutions; a macro like
>
> #define square(x) (x*x)
>
> does not compute "x*x" and return a value; it *replaces* the text
> "square(x)" with "(x*x)". If x is "z++", then the replacement text is
> "(z++*z++)", which invokes undefined behavior. If x is "a+b", then
> the replacement text is "(a+b*a+b)". By using all-uppercase for
> macros, it makes it easier to see potential red flags like "SQUARE(x+
> +)" or "SQUARE(x+y)".
[...]

The side effect problem can't be solved (or at least can't be easily
solved) if you're using a macro, but the operator precedence problem
can.

#define SQUARE(x) ((x)*(x))

You need to parenthesize the entire definition *and* each reference to
the parameter(s).

BTW, here's my favorite example of preprocessor abuse:

#include <stdio.h>

#define SIX 1+5
#define NINE 8+1

int main(void)
{
printf("%d * %d = %d\n", SIX, NINE, SIX * NINE);
return 0;
}

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
From: Scott Lurndal on
Lorenzo Villari <vlllnz(a)tiscali.it> writes:
>On 24 Feb 2010 22:09:43 GMT
>scott(a)slp53.sl.home (Scott Lurndal) wrote:
>
>>
>> if (condition) {
>>
>> is preferred over
>>
>> if (condition)
>> {
>>
>> Makes it much more likely that a properly written function will fit
>> on a single page/screen.
>
>Hmmm...
>
>if (condition) { <-- one line
>
>if (condition) <-- one line
>{ <-- and another one, makes two lines
>
>Does that really make a BIG difference?

On a 24-line screen, you betcha.

scott
From: Scott Lurndal on
Ian Collins <ian-news(a)hotmail.com> writes:
>Scott Lurndal wrote:
>> James Harris <james.harris.1(a)googlemail.com> writes:
>>> On 24 Feb, 20:53, BruceS <bruce...(a)hotmail.com> wrote:
>>>
>>> ...
>>>
>>>> I would like to add that, as long as you're trying to use good style,
>>>> for God's sake don't use the wrong indentation style. =A0If you put your
>>>> opening braces on the same line as your conditional, you'll just look
>>>> like a fool in front of your friends and colleagues.
>>> Snobbish nonsense!
>>>
>>>
>>
>> Indeed.
>>
>> if (condition) {
>>
>> is preferred over
>>
>> if (condition)
>> {
>
>By whom?
>
>> Makes it much more likely that a properly written function will fit on a single
>> page/screen.
>
>If the extra lines required for an opening brace are an issue, the
>function isn't properly written!
>
>> In 30 years of C programming, no employer or project has used the latter form.
>
>I can honestly negate that line.

Ken and Dennis started the trend, and all my employers (operating system vendors)
have followed it.

This fragment is from c00.c (the Unix V6 C compiler (note the obsolete =& operator!)):

/*
* Search the keyword table.
* Ignore initial "." to avoid member-of-structure
* problems.
*/
findkw()
{
register struct kwtab *kp;
register char *p1, *p2;
char *wp;
int firstc;

wp = symbuf;
firstc = *wp;
*wp =& 0177;
for (kp=kwtab; (p2 = kp->kwname); kp++) {
p1 = wp;
while (*p1 == *p2++)
if (*p1++ == '\0') {
cval = kp->kwval;
return(1);
}
}
*wp = firstc;
return(0);
}

scott
From: Rainer Weikusat on
Keith Thompson <kst-u(a)mib.org> writes:
> Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:
>> Keith Thompson <kst-u(a)mib.org> writes:
>>> Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:
>>>> Poster Matt <postermatt(a)no_spam_for_me.org> writes:
>>> [...]
>>>>> 4. Does anyone care where the pointer * is? I prefer keeping to next
>>>>> to the type, rather than next to the variable name.
>>>>>
>>>>> EG. I like: char* firstName; and not so much: char *firstName;
>>>>
>>>> C knows about three kinds of derived types, arrays
>>>>
>>>> char a[];
>>>>
>>>> Pointers to functions
>>>>
>>>> char (*a)();
>>>>
>>>> and pointers
>>>>
>>>> char *a;
>>>
>>> Array types, structure types, union types, function types, and pointer
>>> types are all derived types (C99 6.2.5).
>>
>> Exercise for the reader: Which of the six types defined above are
>> irrelevant for this statement about 'declaration of derived types'
>> because they belong to a different syntactical class than the three
>> examples? Which type is irrelevant because it cannot directly appear
>> in a variable declaration? Which other class of types should appear
>> instead because they can?
>
> You said that "C knows about three kinds of derived types". In fact,
> there are six. I was disputing the accuracy of your statement, not
> its relevance.

Given that these three kinds of derived types exist, my statement was
accurate. I didn't claim that there weren't any other derived types, I
just didn't write about them because they were irrelvant for the
statement I intended to make (this is, of course, just the same kind
of pointless nitpicking).

[...]

>>> But it might be acceptable to special-case on some cases *with*
>>> an understanding of the C type system. I prefer "char *a;" myself,
>>> but there's a valid argument that "char* a;" makes it more obvious
>>> that's meant (that a is of type char*).
>>
>> A type 'char*' doesn't exist. A type named 'char' does, and assuming
>> that T names an existing type, an object can be declared as 'pointer
>> to a T' by using the syntax
>>
>> T *o;
>>
>> 'Pointerness' is an attribute of the object, not of the type. This is
>> also consistent with the original intention behind this syntax, namely
>> that 'declaration should resemble use'.
>
> Wrong. char* is a type. Specifically, it's a derived type and a
> pointer type. See C99 6.2.5, particularly paragraph 20.

T *o;

is a pointer declarator and it means that the type of o is 'pointer to
T', not 'T*' (6.7.5.1|1).

[...]

> (And for the record, I agree that "T *o;" is preferable to
> "T* o;"; I just don't agree that it's a huge deal.)

It's a pointless inconsistency.
From: Keith Thompson on
Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:
> Keith Thompson <kst-u(a)mib.org> writes:
>> Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:
>>> Keith Thompson <kst-u(a)mib.org> writes:
>>>> Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:
[...]
>>>>> C knows about three kinds of derived types, arrays
>>>>>
>>>>> char a[];
>>>>>
>>>>> Pointers to functions
>>>>>
>>>>> char (*a)();
>>>>>
>>>>> and pointers
>>>>>
>>>>> char *a;
>>>>
>>>> Array types, structure types, union types, function types, and pointer
>>>> types are all derived types (C99 6.2.5).
>>>
>>> Exercise for the reader: Which of the six types defined above are
>>> irrelevant for this statement about 'declaration of derived types'
>>> because they belong to a different syntactical class than the three
>>> examples? Which type is irrelevant because it cannot directly appear
>>> in a variable declaration? Which other class of types should appear
>>> instead because they can?
>>
>> You said that "C knows about three kinds of derived types". In fact,
>> there are six. I was disputing the accuracy of your statement, not
>> its relevance.
>
> Given that these three kinds of derived types exist, my statement was
> accurate. I didn't claim that there weren't any other derived types, I
> just didn't write about them because they were irrelvant for the
> statement I intended to make (this is, of course, just the same kind
> of pointless nitpicking).

Ok. I read your statement as implying that C recognizes those three
kinds of derived types and no others. Thanks for the clarification.

[...]

>>> A type 'char*' doesn't exist. A type named 'char' does, and assuming
>>> that T names an existing type, an object can be declared as 'pointer
>>> to a T' by using the syntax
>>>
>>> T *o;
>>>
>>> 'Pointerness' is an attribute of the object, not of the type. This is
>>> also consistent with the original intention behind this syntax, namely
>>> that 'declaration should resemble use'.
>>
>> Wrong. char* is a type. Specifically, it's a derived type and a
>> pointer type. See C99 6.2.5, particularly paragraph 20.
>
> T *o;
>
> is a pointer declarator and it means that the type of o is 'pointer to
> T', not 'T*' (6.7.5.1|1).

So you agree that "pointer to char" is a type, right? The type
"pointer to char" is commonly referred, using C syntax, as "char*".
I see no problem with referring to it that way.

And if the point you were trying to make was the type often referred
to as "char*" is properly referred to as "pointer to char", that
wasn't at all clear to me from what you wrote.

> [...]
>
>> (And for the record, I agree that "T *o;" is preferable to
>> "T* o;"; I just don't agree that it's a huge deal.)
>
> It's a pointless inconsistency.

I don't agree that it's entirely pointless, but I'm not going to argue
the point.

--
Keith Thompson (The_Other_Keith) kst-u(a)mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Prev: integer
Next: shared memory question