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

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post rodchar ASP .Net 2 08-18-2008 03:57 PM Cogito HTML 2 07-21-2007 07:04 AM Opsimath Computer Support 6 11-28-2005 02:58 AM John C Programming 1 06-19-2004 01:22 PM Philip S C Programming 2 11-10-2003 09:34 PM