pls expand this macro

S

sathyashrayan

/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/


#include <stdio.h>


#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
P

Park Sung-jae

sathyashrayan said:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/


#include <stdio.h>


#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

* the macro doesn't know the type of the variable.
if you expand the macro, it looks like this

case 1 / plural_text(0) : &"s"[0]
...
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

* "&" operand will make the right-side variable's pointer
so it makes the array of string which started from the index value
of the array..
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

* << operator shifts the result of "(1==(n))",
so its last value is only be "0" or "2"
"0" will be the "es"
"2" will be the NULL

so you can see the boxes, or box
Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com

I'm poor at english.

- Park, Sung-jae
 
W

Walter Roberson

sathyashrayan said:
#define plural_text(n) &"s"[(1 == (n))]
1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .

No, there is no assignment done. (1 == (n)) is an expression which
produces a value which is either 0 or 1, and the string "s" is indexed
at that offset, and the address (&) of the result is taken.
&"s"[0] is a pointer to the 's' character in a string, but
&"s"[1] is a pointer to the nul that follows the 's'.

In other words the result is either the string "s" or the empty string.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

No, treat the inside as an expression again and look at the offsets
into the string.
 
S

Simon Biber

sathyashrayan said:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/


#include <stdio.h>


#define plural_text(n) &"s"[(1 == (n))]

This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s". If
adding zero, the result is a pointer to the string "s". If adding one,
the result is a pointer to the string "".
#define plural_text2(n) &"es"[(1 == (n))<<1]

This is equivalent to ( "es" + (1 == (n)) * 2 )
ie. adding 0 or 2 to the starting address of the string literal "es". If
adding zero, the result is a pointer to the string "es". If adding two,
the result is a pointer to the string "".
int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i),
> i, plural_text2(i));
return 0;
}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative

That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.
so in the above we could expand the macros as plural_text n[1] = "s" .

No. Not at all. The invocation
plural_text(i)
expands to the following eleven tokens:
& "s" [ ( 1 == ( i ) ) ]
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

No. It acts on an expression, not a variable. The parenthesis are in
case the expression given contains other operators that may affect the
parsing.
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

The & operator is not applied to the array. It is applied to the
expression containing the subscript. That is, it is parsed as
& ( "s"[(1 == (i))] )
rather than
(& "s") [(1 == (i))]

Here's one way to understand it: "s" is an array of two char. That array
is subscripted, to give an lvalue referring to either the first or
second element of the array, and then the address-of operator is applied
to the lvalue, giving a pointer to the first or second element of the array.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

The << operator is a binary shift on an integer value. Shifting left by
one bit is equivalent to multiplying by two. It has the effect of
changing a value that could be 0 or 1, into a value that could be 0 or 2
respectively.
 
S

sathyashrayan

Simon said:
sathyashrayan said:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/


#include <stdio.h>


#define plural_text(n) &"s"[(1 == (n))]

This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s".

"s" is the variable at the base address of the array. == evaluates to true or
false. So if
the array's size should 1 as per the result of == operator evaluation. So
("s" + (1 == (n))) is base + index of array. Correct?

If
adding zero, the result is a pointer to the string "s". If adding one,
the result is a pointer to the string "".

" " in the above sence is '\0' , nul?
#define plural_text2(n) &"es"[(1 == (n))<<1]

This is equivalent to ( "es" + (1 == (n)) * 2 )
ie. adding 0 or 2 to the starting address of the string literal "es". If
adding zero, the result is a pointer to the string "es". If adding two,
the result is a pointer to the string "".
int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i),
i, plural_text2(i));
return 0;
}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative

That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.

Macros are text replacement. So 'n' is replaced with
&"s"[(1 == (n))]

or simply

"s"[0] or "es"[n*2]
So the commutative rule does not apply hear. Correct?

so in the above we could expand the macros as plural_text n[1] = "s" .

No. Not at all. The invocation
plural_text(i)
expands to the following eleven tokens:
& "s" [ ( 1 == ( i ) ) ]

understood
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

No. It acts on an expression, not a variable. The parenthesis are in
case the expression given contains other operators that may affect the
parsing.

Arguments in macros evaluates only once for every call and also itself.
There is a famous example covered in almost all C books about macro pit fall.
I dont remember that at present.
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

The & operator is not applied to the array. It is applied to the
expression containing the subscript. That is, it is parsed as
& ( "s"[(1 == (i))] )
rather than
(& "s") [(1 == (i))]

Here's one way to understand it: "s" is an array of two char. That array
is subscripted, to give an lvalue referring to either the first or
second element of the array, and then the address-of operator is applied
to the lvalue, giving a pointer to the first or second element of the array.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

The << operator is a binary shift on an integer value. Shifting left by
one bit is equivalent to multiplying by two. It has the effect of
changing a value that could be 0 or 1, into a value that could be 0 or 2
respectively.

Thanks. I am clear with the rest of explanation.


--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
N

Netocrat

/*
** PLURALTX.C - How to print proper plurals ** public domain -
original algorithm by Bob Stout */


#include <stdio.h>


#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .

That expansion isn't correct. In this situation, the array is "s". "s"
is known as a string literal and here it is equivalent to a char array of
size two, first member 's' and second member '\0' ('\0' is the string
terminating character which is identical to integer 0, and is sometimes
confusing referred to as NUL).

So indexing can be applied to that array:
"s"[0] gives the first array element, the character 's'
"s"[1] gives the second array element, the terminating character '\0'.

This has the same effect as first declaring:
char str[2] = "s";
and then indexing as:
str[0] and str[1]

The property of subscripting that you're referring to means that:
str[0] is identical to writing 0[str]
str[1] is identical to writing 1[str]
"s"[0] is identical to writing 0["s"]
"s"[1] is identical to writing 1["s"]
"s"[(1 == (n))] is identical to writing (1 == (n))["s"]
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

The macro doesn't and can't know the type of its parameter and parentheses
do nothing to help it. What they're actually there for is to prevent
unintended precedence if n is a complex expression.

It might be easier to consider a simpler situation to show why
parenthesising macro parameters is good practice. The result of double(x
+ 1) and double_safe(x + 1) given the code below will be different, and
only the second form will give the expected result:

#define double(n) 2 * n
#define double_safe(n) 2 * (n)
int x = 1;
2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into the pointer to it's first
element"?

Actually the & operator isn't making direct use of that rule. See the
description below.
3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

The second macro:
#define plural_text2(n) &"es"[(1 == (n))<<1]

can be simplified to:
#define plural_text2(n) &string_array[index]

where string_array is "es" and index is (1 == (n))<<1

Now consider (1 == (n))

This will be 1 when n is 1 and 0 when n is other than 1.

So the index will be either:
1<<1, or 0<<1

The first expression results in 2, and the second results in 0.

So "es" is being indexed at 2 or 0, and then its address is taken.

Indexing "es" at 2 results in the terminating '\0' character element, and
the & operator returns the address of this element. The final result is
an empty string (a pointer to a terminating character element).

Indexing "es" at 0 results in the first character element, 'e', and the &
operator returns the address of this element, which is the same as the
string "es" (because being an array, "es" decays into a pointer to its
first element - this is the rule you described).

So when n is 1, the macro results in an empty string - which is expected -
a single element doesn't have a plural form. When n is 0 or greater than
1, the macro results in the string "es" - which is again expected.
 
S

sathyashrayan

thanks for all the explanation.
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/

#include <stdio.h>

#define plural_text(n) &"s"[(1 == (n))]

#define plural_text2(n) &"es"[(1 == (n))<<1]

int main(void)
{
int i;

for (i = 0; i < 10; ++i)
printf("%d thing%s in %d box%s\n", i, plural_text(i), i,
plural_text2(i));
return 0;

}

My questions:

1) I try to understand the two macros plural_text and plural_text2.
array subscripting is commutative
so in the above we could expand the macros as plural_text n[1] = "s" .
The parenthesis around
the variable (n) since the macros does not know the type of the variable
it is acting on. Am I correct?

2) I don't able to understand the use of & in both of the macros. Does
it used for the rule "array decays into
the pointer to it's first element"?

3) << operator in the macro plural_text2 used to move the string to the
second one, in the above case
it is "s". Correct?

Can any one explain both of the macros.
--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com

--
"combination is the heart of chess"

A.Alekhine

Mail to:
sathyashrayan AT gmail DOT com
 
S

sathyashrayan

[sniped...]
Arguments in macros evaluates only once for every call and also itself.
There is a famous example covered in almost all C books about macro pit fall.
I dont remember that at present.

netocrat explained the answer in the other thread.

[
 
S

Simon Biber

sathyashrayan said:
Simon said:
sathyashrayan said:
/*
** PLURALTX.C - How to print proper plurals
** public domain - original algorithm by Bob Stout
*/

#include <stdio.h>

#define plural_text(n) &"s"[(1 == (n))]

This is equivalent to ( "s" + (1 == (n) ) )
ie. adding 0 or 1 to the starting address of the string literal "s".

"s" is the variable at the base address of the array. == evaluates to true or
false. So if
the array's size should 1 as per the result of == operator evaluation. So
("s" + (1 == (n))) is base + index of array. Correct?

When an array is used in any expression, except as the argument of & or
sizeof, it is implicitly converted into a pointer to the first element
of an array.

"s" is an array. The size of the array is 2. The first element of the
array is (char) 's', and the second element of the array is (char) 0,
ie. a null character.

Here it is used as the argument of the [ ] operator (in the original),
or the + operator (in my equivalent expression), but not the & operator.
So, it is implicitly converted into a pointer to the first element of
the array. That pointer points to the 's' character.

If the parameter n has the value 1, then the expression (1 == (n))
evaluates to 1, and the result is a pointer to the second element of the
array, which is a null character.

A pointer to a null character is an empty string, and so when passed to
printf with the %s specifier, nothing will be printed.
" " in the above sence is '\0' , nul?

I wrote "" (with nothing between the quotes), not " " (with a space
between the quotes). The result is a pointer to the null character of
the string "s".

The term "nul" is ASCII-specific, and is not the correct term used in C.
That's irrelevant. This code uses array subscripting in the usual way,
with the array on the left, and the subscript between the brackets.


Macros are text replacement. So 'n' is replaced with
&"s"[(1 == (n))]

Macros are expanded as preprocessing tokens, rather than plain text, but
the effect is usually the same.

What makes you think 'n' is replaced with anything?
Suppose I write out the tokens, one on each line, with
...
...
...
representing a sequence of zero or more tokens.

When the preprocessor comes across the tokens
plural_text
(
...
...
...
)

they are replaced with
&
"s"
[
(
1
==
(
...
...
...
)
)
]
or simply

"s"[0] or "es"[n*2]

No! You have left out the & operator. And n is never multiplied by 2.

The result of plural_text(i) is always a pointer to one of the elements
of the string literal "s". Either a pointer to the 's' or a pointer to
the null character.

The result of plural_text2(i) is always a pointer to one of the elements
of the string literal "es". Either a pointer to the 'e' or a pointer to
the null character.
So the commutative rule does not apply hear. Correct?

The commutative rule for array subscripting means that
array[index]
is equivalent to
index[array]

But in these two macros, the array is in the conventional position on
the left of the brackets, and the index is in the conventional position
between the brackets. There is no need to apply the rule.
 

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,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top