Velocity Reviews > deciphering a macro

# deciphering a macro

Uno
Guest
Posts: n/a

 07-01-2010
This is Plauger's macro override for putc:

#define putc(c, str) ((str)->_Next < (str)->_Wend \
? (*(str)->_Next++ = c) : (putc)(c, str))

So if str._Next is less than str._Wend then
str._Next, iterated once, equals c
else
you have to call the definition of putc.

How did I do with the logic on that?

Thanks for your comment, and cheers,
--
Uno

Eric Sosman
Guest
Posts: n/a

 07-01-2010
On 6/30/2010 10:24 PM, Uno wrote:
> This is Plauger's macro override for putc:
>
> #define putc(c, str) ((str)->_Next < (str)->_Wend \
> ? (*(str)->_Next++ = c) : (putc)(c, str))
>
> So if str._Next is less than str._Wend then
> str._Next, iterated once, equals c
> else
> you have to call the definition of putc.
>
> How did I do with the logic on that?

Your phrasing suggests that the pointer is incremented before
the character is stored, which it's not. I'd have preferred "store
c where str->_Next points, and increment str->_Next."

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)lid

Uno
Guest
Posts: n/a

 07-01-2010
Eric Sosman wrote:
> On 6/30/2010 10:24 PM, Uno wrote:
>> This is Plauger's macro override for putc:
>>
>> #define putc(c, str) ((str)->_Next < (str)->_Wend \
>> ? (*(str)->_Next++ = c) : (putc)(c, str))
>>
>> So if str._Next is less than str._Wend then
>> str._Next, iterated once, equals c
>> else
>> you have to call the definition of putc.
>>
>> How did I do with the logic on that?

>
> Your phrasing suggests that the pointer is incremented before
> the character is stored, which it's not. I'd have preferred "store
> c where str->_Next points, and increment str->_Next."
>

Thx, eric.

if the value where str->_Next points is less than the value where
str->_Wend points then store c where str->_Next points, and increment
str->_Next, otherwise use the function.

Better?

I'm looking for more of this source, but as a macro neophyte, I have no
method for this.

Does this tell you anything?

typedef struct {
unsigned short _Mode;
short _Handle;
unsigned char *_Buf, *_Bend, *_Next;
unsigned char *_Rend, *_Rsave, *_Wend;
unsigned char _Back[2], _Cbuf, _Nback;
char *_Tmpnam;
} FILE;
--
Uno

Vincenzo Mercuri
Guest
Posts: n/a

 07-01-2010
Uno wrote:

> if the value where str->_Next points is less than the value where
> str->_Wend points then store c where str->_Next points, and increment
> str->_Next, otherwise use the function.

Here you are dealing with pointers. It means:
if the memory address str->_Next is lower than the memory
address str->_Wend, the comparison '<' refers to pointers
not to values pointed to.

--
Vincenzo Mercuri

Uno
Guest
Posts: n/a

 07-01-2010
Vincenzo Mercuri wrote:
> Uno wrote:
>
>> if the value where str->_Next points is less than the value where
>> str->_Wend points then store c where str->_Next points, and increment
>> str->_Next, otherwise use the function.

>
> Here you are dealing with pointers. It means:
> if the memory address str->_Next is lower than the memory
> address str->_Wend, the comparison '<' refers to pointers
> not to values pointed to.
>
>
>
>

if the memory address str->_Next points is numerically less than the
memory address str->_Wend points to, then store c where str->_Next
points, and increment str->_Next, otherwise use the function.

?
--
Uno

Francois Grieu
Guest
Posts: n/a

 07-01-2010
Uno commented the following library code:

typedef struct {
unsigned short _Mode;
short _Handle;
unsigned char *_Buf, *_Bend, *_Next;
unsigned char *_Rend, *_Rsave, *_Wend;
unsigned char _Back[2], _Cbuf, _Nback;
char *_Tmpnam;
} FILE;

#define putc(c, str) ((str)->_Next < (str)->_Wend \
? (*(str)->_Next++ = c) : (putc)(c, str))

> if the memory address str->_Next points is numerically less than the
> memory address str->_Wend points to, then store c where str->_Next
> points, and increment str->_Next, otherwise use the function.

Yes. The macro putc is an alternative to the function putc,
that does not involve a function call, but behaves like a function
(although one can't take its address). It works by caching write into
a memory buffer (presumably _Buf), endind at _Bend, with current
pointer at _Next. If that can't work [e.g. when the buffer is full,
this corresponds to !((str)->_Next < (str)->_Wend) ], the function
putc is called. On many machines, this speeds up putc by several
binary orders of magnitude.

François Grieu

Uno
Guest
Posts: n/a

 07-01-2010
Francois Grieu wrote:
> Uno commented the following library code:
>
> typedef struct {
> unsigned short _Mode;
> short _Handle;
> unsigned char *_Buf, *_Bend, *_Next;
> unsigned char *_Rend, *_Rsave, *_Wend;
> unsigned char _Back[2], _Cbuf, _Nback;
> char *_Tmpnam;
> } FILE;
>
> #define putc(c, str) ((str)->_Next < (str)->_Wend \
> ? (*(str)->_Next++ = c) : (putc)(c, str))
>
>
>> if the memory address str->_Next points is numerically less than the
>> memory address str->_Wend points to, then store c where str->_Next
>> points, and increment str->_Next, otherwise use the function.

>
> Yes. The macro putc is an alternative to the function putc,
> that does not involve a function call, but behaves like a function
> (although one can't take its address). It works by caching write into
> a memory buffer (presumably _Buf), endind at _Bend, with current
> pointer at _Next. If that can't work [e.g. when the buffer is full,
> this corresponds to !((str)->_Next < (str)->_Wend) ], the function
> putc is called. On many machines, this speeds up putc by several
> binary orders of magnitude.

Is the definition of the _Next in the #define from this struct?
--
Uno

Francois Grieu
Guest
Posts: n/a

 07-01-2010
Le 01/07/2010 09:52, Uno a écrit :
> Francois Grieu wrote:
>> Uno commented the following library code:
>>
>> typedef struct {
>> unsigned short _Mode;
>> short _Handle;
>> unsigned char *_Buf, *_Bend, *_Next;
>> unsigned char *_Rend, *_Rsave, *_Wend;
>> unsigned char _Back[2], _Cbuf, _Nback;
>> char *_Tmpnam;
>> } FILE;
>>
>> #define putc(c, str) ((str)->_Next < (str)->_Wend \
>> ? (*(str)->_Next++ = c) : (putc)(c, str))
>>
>>
>>> if the memory address str->_Next points is numerically less than the
>>> memory address str->_Wend points to, then store c where str->_Next
>>> points, and increment str->_Next, otherwise use the function.

>>
>> Yes. The macro putc is an alternative to the function putc,
>> that does not involve a function call, but behaves like a function
>> (although one can't take its address). It works by caching write into
>> a memory buffer (presumably _Buf), endind at _Bend, with current
>> pointer at _Next. If that can't work [e.g. when the buffer is full,
>> this corresponds to !((str)->_Next < (str)->_Wend) ], the function
>> putc is called. On many machines, this speeds up putc by several
>> binary orders of magnitude.

>
> Is the definition of the _Next in the #define from this struct?

Yes. In putc, the second parameter is a pointer to FILE.

Francois Grieu

Eric Sosman
Guest
Posts: n/a

 07-01-2010
On 6/30/2010 11:03 PM, Uno wrote:
> Eric Sosman wrote:
>> On 6/30/2010 10:24 PM, Uno wrote:
>>> This is Plauger's macro override for putc:
>>>
>>> #define putc(c, str) ((str)->_Next < (str)->_Wend \
>>> ? (*(str)->_Next++ = c) : (putc)(c, str))
>>>
>>> So if str._Next is less than str._Wend then
>>> str._Next, iterated once, equals c
>>> else
>>> you have to call the definition of putc.
>>>
>>> How did I do with the logic on that?

>>
>> Your phrasing suggests that the pointer is incremented before
>> the character is stored, which it's not. I'd have preferred "store
>> c where str->_Next points, and increment str->_Next."
>>

>
> Thx, eric.
>
> if the value where str->_Next points is less than the value where
> str->_Wend points then store c where str->_Next points, and increment
> str->_Next, otherwise use the function.
>
> Better?

It still seems a bit confused, or maybe just a little baroque.
How about "If the value of str->_Next is less than the value of
str->_Wend, store c where str->_Wend points and advance str->_Wend,
otherwise use the function."

> I'm looking for more of this source, but as a macro neophyte, I have no
> method for this.

Do you have the book the source comes from? It's a good book
and does a good job of explaining why the source looks the way it
does, but it presupposes a certain proficiency in C. If you're
just looking at the source without the book's explanations (and
especially if you're the neophyte you say you are), I don't think
you're likely to gain much understanding. Get the book if you

--
Eric Sosman
(E-Mail Removed)lid

Uno
Guest
Posts: n/a

 07-02-2010
Eric Sosman wrote:

>> I'm looking for more of this source, but as a macro neophyte, I have no
>> method for this.

>
> Do you have the book the source comes from? It's a good book
> and does a good job of explaining why the source looks the way it
> does, but it presupposes a certain proficiency in C. If you're
> just looking at the source without the book's explanations (and
> especially if you're the neophyte you say you are), I don't think
> you're likely to gain much understanding. Get the book if you
>

What I meant when I said that I was looking for more of this source, I
was trying to find it on my own system, with which I have only 6 months
experience. My search for stdio.h turned up 7 results, and I was sunk.

Plauger's book is fascinating, and he was nice enough to send me the
source, so if I have trouble with any part of it, I can learn from my
compiler. (or copy, paste, and post to usenet)

It will be the only book that comes with me to Lake Heron, NM now for 4
days of camping at 7200 feet. I'll waive to you in your Arizona swelter.
--
Uno