Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #70056 > unrolled thread

Re: just curious:Equel

Started byTim Rentsch <txr@alumni.caltech.edu>
First post2015-09-09 10:22 -0700
Last post2015-09-29 10:03 -0700
Articles 19 — 6 participants

Back to article view | Back to comp.lang.c

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-09 10:22 -0700
    Re: just curious:Equel August Karlstrom <fusionfile@gmail.com> - 2015-09-10 10:21 +0200
      Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-11 12:06 -0700
        Re: just curious:Equel August Karlstrom <fusionfile@gmail.com> - 2015-09-12 17:53 +0200
          Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-26 16:04 -0700
            Re: just curious:Equel Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-09-26 16:17 -0700
              Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-01 12:53 -0700
            Re: just curious:Equel August Karlstrom <fusionfile@gmail.com> - 2015-09-28 18:00 +0200
              Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-01 12:51 -0700
      Re: just curious:Equel Philip Lantz <prl@canterey.us> - 2015-09-23 22:18 -0700
        Re: just curious:Equel August Karlstrom <fusionfile@gmail.com> - 2015-09-24 10:08 +0200
          Re: just curious:Equel Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-24 10:23 +0100
            Re: just curious:Equel Philip Lantz <prl@canterey.us> - 2015-09-24 10:28 -0700
              Re: just curious:Equel Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-09-24 19:56 +0100
          Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-26 16:16 -0700
            Re: just curious:Equel August Karlstrom <fusionfile@gmail.com> - 2015-09-28 08:18 +0200
        Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-26 16:10 -0700
          Re: just curious:Equel supercat@casperkitty.com - 2015-09-27 11:40 -0700
            Re: just curious:Equel Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-29 10:03 -0700

#70056 — Re: just curious:Equel

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-09 10:22 -0700
SubjectRe: just curious:Equel
Message-ID<kfnlhcfld75.fsf@x-alumni2.alumni.caltech.edu>
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-08 08:12, Tim Rentsch wrote:
>> August Karlstrom <fusionfile@gmail.com> writes:
>>> Easier is just NEW(p) after having defined NEW as
>>>
>>> #define NEW(ptr) (ptr) = malloc(sizeof *(ptr))
>>
>> I sometimes use this technique, mainly for better factoring.
>
> Yes, it makes it easier to switch to a different allocator, like for
> instance GC_MALLOC.
>
>> Also a two-argument form that allows allocating an array.
>
> Indeed.  These are the three function macros I always use in my projects:
>
>     #include <stdlib.h>
>
>     #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>
>     #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>
>     #define NEW(ptr) NEW_ARRAY((ptr), 1)

I agree on the macros, although I would advocate different
choices for the names.  I've settled on LIMIT() for what you call
LEN().  (As a rule I avoided shortened words like "len" and "ptr"
- if a word is meant, better to use the whole word.)  For the
NEW's, my naming heuristics say the more general form should
have the shorter name, so maybe NEW(p,n) and NEW1(p) (or perhaps
MALLOC(p) for the second one?).  For what that's worth.

Incidentally, you probably know this, but these NEW's can be used
as parts of declarations:

    int *NEW( stuff, 20 );

I expect some people would frown on that kind of usage.  I agree
that it might seem a little weird, but not so much as to not use
it;  after all, the similarity of initializing declarations and
assigments is not accidental, so even if the idiom is somewhat
surprising it shouldn't be overly so.

[toc] | [next] | [standalone]


#70132

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-10 10:21 +0200
Message-ID<msrehd$d8j$1@speranza.aioe.org>
In reply to#70056
On 2015-09-09 19:22, Tim Rentsch wrote:
> August Karlstrom <fusionfile@gmail.com> writes:
>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>
>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>
>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>
> I agree on the macros, although I would advocate different choices
> for the names.  I've settled on LIMIT() for what you call LEN().  (As
> a rule I avoided shortened words like "len" and "ptr" - if a word is
> meant, better to use the whole word.)

It's always a question of striking a balance between identifier 
comprehension and expression/statement comprehension.

The *length* of an array is a well established concept. On the other 
hand I'm not familiar with the *limit* of an array. If I saw your LIMIT 
function I wouldn't know if it was the index of the last element or the 
length of an array.

> Incidentally, you probably know this, but these NEW's can be used as
> parts of declarations:
>
> int *NEW( stuff, 20 );

Or "misused", depending on how you see it. ;-)


-- August

[toc] | [prev] | [next] | [standalone]


#70270

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-11 12:06 -0700
Message-ID<kfna8sskc6s.fsf@x-alumni2.alumni.caltech.edu>
In reply to#70132
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-09 19:22, Tim Rentsch wrote:
>> August Karlstrom <fusionfile@gmail.com> writes:
>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>
>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>
>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>>
>> I agree on the macros, although I would advocate different choices
>> for the names.  I've settled on LIMIT() for what you call LEN().  (As
>> a rule I avoided shortened words like "len" and "ptr" - if a word is
>> meant, better to use the whole word.)
>
> It's always a question of striking a balance between identifier
> comprehension and expression/statement comprehension.
>
> The *length* of an array is a well established concept.  On the other
> hand I'm not familiar with the *limit* of an array.  If I saw your
> LIMIT function I wouldn't know if it was the index of the last element
> or the length of an array.

I think either name is okay.  Personally I would shy away from
LENGTH() because (a) the term "length" is pretty overloaded (eg,
strlen()), and (b) I don't think of what I'm asking for the
"length" but the "limit" (under the usual C idioms) of index
values for the array.  It happens that "limit" and "length"
here are equal, and that isn't just a coincidence, but still
"limit" does a better job (to me) of conveying what I'm asking
for.  But to repeat myself, I think either name is okay.

>> Incidentally, you probably know this, but these NEW's can be used as
>> parts of declarations:
>>
>> int *NEW( stuff, 20 );
>
> Or "misused", depending on how you see it. ;-)

I'm sure some people do see it that way.  I myself don't have so
strong a reaction as that.  Generally I like to save up my
judgmental disapproval for constructs that are unequivocally
inexcusable, and this one doesn't rise to that level.

[toc] | [prev] | [next] | [standalone]


#70355

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-12 17:53 +0200
Message-ID<mt1hp5$qal$1@speranza.aioe.org>
In reply to#70270
On 2015-09-11 21:06, Tim Rentsch wrote:
> August Karlstrom <fusionfile@gmail.com> writes:
>> The *length* of an array is a well established concept.  On the other
>> hand I'm not familiar with the *limit* of an array.  If I saw your
>> LIMIT function I wouldn't know if it was the index of the last element
>> or the length of an array.
>
> I think either name is okay.  Personally I would shy away from
> LENGTH() because (a) the term "length" is pretty overloaded (eg,
> strlen())

That's true. We mustn't mix up the concepts of string length and 
(character) array length.

>>> Incidentally, you probably know this, but these NEW's can be used as
>>> parts of declarations:
>>>
>>> int *NEW( stuff, 20 );
>>
>> Or "misused", depending on how you see it. ;-)
>
> I'm sure some people do see it that way.  I myself don't have so
> strong a reaction as that.  Generally I like to save up my
> judgmental disapproval for constructs that are unequivocally
> inexcusable, and this one doesn't rise to that level.

Personally, I only use macros when nothing else will do, and I only use 
them in non-clever ways.


-- August

[toc] | [prev] | [next] | [standalone]


#71239

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-26 16:04 -0700
Message-ID<kfn1tdkg4u0.fsf@x-alumni2.alumni.caltech.edu>
In reply to#70355
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-11 21:06, Tim Rentsch wrote:
>> August Karlstrom <fusionfile@gmail.com> writes:
>>> The *length* of an array is a well established concept.  On the other
>>> hand I'm not familiar with the *limit* of an array.  If I saw your
>>> LIMIT function I wouldn't know if it was the index of the last element
>>> or the length of an array.
>>
>> I think either name is okay.  Personally I would shy away from
>> LENGTH() because (a) the term "length" is pretty overloaded (eg,
>> strlen())
>
> That's true.  We mustn't mix up the concepts of string length and
> (character) array length.
>
>>>> Incidentally, you probably know this, but these NEW's can be used as
>>>> parts of declarations:
>>>>
>>>> int *NEW( stuff, 20 );
>>>
>>> Or "misused", depending on how you see it. ;-)
>>
>> I'm sure some people do see it that way.  I myself don't have so
>> strong a reaction as that.  Generally I like to save up my
>> judgmental disapproval for constructs that are unequivocally
>> inexcusable, and this one doesn't rise to that level.
>
> Personally, I only use macros when nothing else will do, and I only
> use them in non-clever ways.

I use macros sparingly, when I think a macro is the best way (or
at least the best I can think of) to express what I'm trying to
convey.

Given your comments about macros NEW(), etc, how would you
write an allocating declaration that started, eg,

    struct foo *const ...

?

[toc] | [prev] | [next] | [standalone]


#71242

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2015-09-26 16:17 -0700
Message-ID<b928dae0-962e-4161-bfef-1b19b098d8d5@googlegroups.com>
In reply to#71239
On Sunday, September 27, 2015 at 12:04:52 AM UTC+1, Tim Rentsch wrote:
> 
> I use macros sparingly, when I think a macro is the best way (or
> at least the best I can think of) to express what I'm trying to
> convey.
> 
If you add a layer of abstraction, you also obscure what the code
actually says. There are also subtle programs.

e.g

#define MAX_PATH 256

OK, does that mean that a path can go to 256 or 255 characters?
Can we simply replace the value with something else, or are there
other constraints (e.g is the path length stored at some point in
an 8 bit byte, does it have to be a power of 2 or a multiple
of 256 or of 4, will changing the value break existing records,
will do so but only if there happen to be existing records with
paths greater than the new length?). There's too much to document.

[toc] | [prev] | [next] | [standalone]


#71563

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-10-01 12:53 -0700
Message-ID<kfnsi5u9xgy.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71242
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> On Sunday, September 27, 2015 at 12:04:52 AM UTC+1, Tim Rentsch wrote:
>
>> I use macros sparingly, when I think a macro is the best way (or
>> at least the best I can think of) to express what I'm trying to
>> convey.
>
> If you add a layer of abstraction, you also obscure what the code
> actually says.  There are also subtle programs.
>
> e.g
>
> #define MAX_PATH 256
>
> OK, does that mean that a path can go to 256 or 255 characters?
> Can we simply replace the value with something else, or are there
> other constraints (e.g is the path length stored at some point in
> an 8 bit byte, does it have to be a power of 2 or a multiple
> of 256 or of 4, will changing the value break existing records,
> will do so but only if there happen to be existing records with
> paths greater than the new length?).  There's too much to document.

For some reason this reminds me of Lewis Carroll:  "If it was so, it
might be; and if it were so, it would be; but as it isn't, it
ain't. That's logic."

[toc] | [prev] | [next] | [standalone]


#71375

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-28 18:00 +0200
Message-ID<mubo6t$3sp$1@speranza.aioe.org>
In reply to#71239
On 2015-09-27 01:04, Tim Rentsch wrote:
 >>>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>>>> Incidentally, you probably know this, but these NEW's can be used as
>>>>> parts of declarations:
>>>>>
>>>>> int *NEW( stuff, 20 );
[...]
> Given your comments about macros NEW(), etc, how would you
> write an allocating declaration that started, eg,
>
>      struct foo *const ...
>
> ?

OK, here you seem to have a use-case for

	struct foo *const NEW(v) ...

I must admit that I have never used constant pointers in my programs.


-- August

[toc] | [prev] | [next] | [standalone]


#71561

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-10-01 12:51 -0700
Message-ID<kfnwpv69xlc.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71375
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-27 01:04, Tim Rentsch wrote:
>>>>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>>>>> Incidentally, you probably know this, but these NEW's can be used as
>>>>>> parts of declarations:
>>>>>>
>>>>>> int *NEW( stuff, 20 );
>
> [...]
>
>> Given your comments about macros NEW(), etc, how would you
>> write an allocating declaration that started, eg,
>>
>>      struct foo *const ...
>>
>> ?
>
> OK, here you seem to have a use-case for
>
>     struct foo *const NEW(v) ...
>
> I must admit that I have never used constant pointers in my programs.

I think of the use case as wanting to initialize a pointer to an
allocated block in the pointer's declaration.  The const is there
just to be sure that case is addressed squarely, rather than
being sidestepped via some awful workaround.

[toc] | [prev] | [next] | [standalone]


#71161

FromPhilip Lantz <prl@canterey.us>
Date2015-09-23 22:18 -0700
Message-ID<MPG.306d279abfa29e7863@news.eternal-september.org>
In reply to#70132
On 2015-09-10, August Karlstrom wrote:
> On 2015-09-09 19:22, Tim Rentsch wrote:
> > August Karlstrom <fusionfile@gmail.com> writes:
> >> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
> >>
> >> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
> >>
> >> #define NEW(ptr) NEW_ARRAY((ptr), 1)
> >
> > Incidentally, you probably know this, but these NEW's can be used as
> > parts of declarations:
> >
> > int *NEW( stuff, 20 );
> 
> Or "misused", depending on how you see it. ;-)

Perhaps Tim was slyly pointing out that you omitted the usual 
parentheses around the macro expansion.

Oh, I see from his next response that he probably wasn't. But fully 
parenthesizing macros that expand to expressions is generally considered 
good form, and it would prevent the "misuse", should you care to do so.

Philip

[toc] | [prev] | [next] | [standalone]


#71165

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-24 10:08 +0200
Message-ID<mu0b1k$vf1$1@speranza.aioe.org>
In reply to#71161
On 2015-09-24 07:18, Philip Lantz wrote:
> On 2015-09-10, August Karlstrom wrote:
>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>> August Karlstrom <fusionfile@gmail.com> writes:
>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>>
>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>>
>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>>>
>>> Incidentally, you probably know this, but these NEW's can be used as
>>> parts of declarations:
>>>
>>> int *NEW( stuff, 20 );
>>
>> Or "misused", depending on how you see it. ;-)
>
> Perhaps Tim was slyly pointing out that you omitted the usual
> parentheses around the macro expansion.
>
> Oh, I see from his next response that he probably wasn't. But fully
> parenthesizing macros that expand to expressions is generally considered
> good form, and it would prevent the "misuse", should you care to do so.

I'm thinking that the macro NEW is semantically a function call 
*statement*. Therefor it's not meant to be used  in expressions (or in 
declarations like the one above).


-- August

[toc] | [prev] | [next] | [standalone]


#71166

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-09-24 10:23 +0100
Message-ID<87vbb0f9w4.fsf@bsb.me.uk>
In reply to#71165
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-24 07:18, Philip Lantz wrote:
>> On 2015-09-10, August Karlstrom wrote:
>>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>>> August Karlstrom <fusionfile@gmail.com> writes:
>>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>>>
>>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>>>
>>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>>>>
>>>> Incidentally, you probably know this, but these NEW's can be used as
>>>> parts of declarations:
>>>>
>>>> int *NEW( stuff, 20 );
>>>
>>> Or "misused", depending on how you see it. ;-)
>>
>> Perhaps Tim was slyly pointing out that you omitted the usual
>> parentheses around the macro expansion.
>>
>> Oh, I see from his next response that he probably wasn't. But fully
>> parenthesizing macros that expand to expressions is generally considered
>> good form, and it would prevent the "misuse", should you care to do so.
>
> I'm thinking that the macro NEW is semantically a function call
> *statement*. Therefor it's not meant to be used  in expressions (or in
> declarations like the one above).

If you want, you can enforce that rule by writing the macro like this:

#define NEW_ARRAY(ptr, n) do (ptr) = malloc((n) * sizeof *(ptr)); while (0)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71179

FromPhilip Lantz <prl@canterey.us>
Date2015-09-24 10:28 -0700
Message-ID<MPG.306dd2a3c60d906566@news.eternal-september.org>
In reply to#71166
Ben Bacarisse wrote:
> 
> August Karlstrom <fusionfile@gmail.com> writes:
> 
> > On 2015-09-24 07:18, Philip Lantz wrote:
> >> On 2015-09-10, August Karlstrom wrote:
> >>> On 2015-09-09 19:22, Tim Rentsch wrote:
> >>>> August Karlstrom <fusionfile@gmail.com> writes:
> >>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
> >>>>>
> >>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
> >>>>>
> >>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
> >>>>
> >>>> Incidentally, you probably know this, but these NEW's can be used as
> >>>> parts of declarations:
> >>>>
> >>>> int *NEW( stuff, 20 );
> >>>
> >>> Or "misused", depending on how you see it. ;-)
> >>
> >> Perhaps Tim was slyly pointing out that you omitted the usual
> >> parentheses around the macro expansion.
> >>
> >> Oh, I see from his next response that he probably wasn't. But fully
> >> parenthesizing macros that expand to expressions is generally considered
> >> good form, and it would prevent the "misuse", should you care to do so.
> >
> > I'm thinking that the macro NEW is semantically a function call
> > *statement*. Therefor it's not meant to be used  in expressions (or in
> > declarations like the one above).
> 
> If you want, you can enforce that rule by writing the macro like this:
> 
> #define NEW_ARRAY(ptr, n) do (ptr) = malloc((n) * sizeof *(ptr)); while (0)

Or
#define NEW_ARRAY(ptr, n) ((void)((ptr) = malloc((n) * sizeof *(ptr))))
which would be my preference.

[toc] | [prev] | [next] | [standalone]


#71183

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-09-24 19:56 +0100
Message-ID<87k2rffxy1.fsf@bsb.me.uk>
In reply to#71179
Philip Lantz <prl@canterey.us> writes:

> Ben Bacarisse wrote:
>> 
>> August Karlstrom <fusionfile@gmail.com> writes:
>> 
>> > On 2015-09-24 07:18, Philip Lantz wrote:
>> >> On 2015-09-10, August Karlstrom wrote:
>> >>> On 2015-09-09 19:22, Tim Rentsch wrote:
>> >>>> August Karlstrom <fusionfile@gmail.com> writes:
>> >>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>> >>>>>
>> >>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>> >>>>>
>> >>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>> >>>>
>> >>>> Incidentally, you probably know this, but these NEW's can be used as
>> >>>> parts of declarations:
>> >>>>
>> >>>> int *NEW( stuff, 20 );
>> >>>
>> >>> Or "misused", depending on how you see it. ;-)
>> >>
>> >> Perhaps Tim was slyly pointing out that you omitted the usual
>> >> parentheses around the macro expansion.
>> >>
>> >> Oh, I see from his next response that he probably wasn't. But fully
>> >> parenthesizing macros that expand to expressions is generally considered
>> >> good form, and it would prevent the "misuse", should you care to do so.
>> >
>> > I'm thinking that the macro NEW is semantically a function call
>> > *statement*. Therefor it's not meant to be used  in expressions (or in
>> > declarations like the one above).
>> 
>> If you want, you can enforce that rule by writing the macro like this:
>> 
>> #define NEW_ARRAY(ptr, n) do (ptr) = malloc((n) * sizeof *(ptr)); while (0)
>
> Or
> #define NEW_ARRAY(ptr, n) ((void)((ptr) = malloc((n) * sizeof *(ptr))))
> which would be my preference.

Sure, though that does not, technically, stop it being using in
expressions.  I don't mean that it can be used as the sole expression in
an expression statement -- that's obviously the purpose -- but it can
also be used in a comma expression or, more oddly, in a conditional
expression.  I don't think this matters much.  In fact both such uses
could be considered "statement-like" and therefore perfectly acceptable
even to someone who wants to exclude the macro from expression.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#71241

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-26 16:16 -0700
Message-ID<kfnsi60eppt.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71165
August Karlstrom <fusionfile@gmail.com> writes:

> On 2015-09-24 07:18, Philip Lantz wrote:
>> On 2015-09-10, August Karlstrom wrote:
>>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>>> August Karlstrom <fusionfile@gmail.com> writes:
>>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>>>
>>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>>>
>>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>>>>
>>>> Incidentally, you probably know this, but these NEW's can be used as
>>>> parts of declarations:
>>>>
>>>> int *NEW( stuff, 20 );
>>>
>>> Or "misused", depending on how you see it. ;-)
>>
>> Perhaps Tim was slyly pointing out that you omitted the usual
>> parentheses around the macro expansion.
>>
>> Oh, I see from his next response that he probably wasn't.  But fully
>> parenthesizing macros that expand to expressions is generally considered
>> good form, and it would prevent the "misuse", should you care to do so.
>
> I'm thinking that the macro NEW is semantically a function call
> *statement*. Therefor it's not meant to be used  in expressions (or in
> declarations like the one above).

That seems odd to me (talking just about the expressions part,
not the declarations part).  I can see not wanting to make the
value available, like a (void) function, but not restricted
to just being a statement.  Or am I not understanding you?

[toc] | [prev] | [next] | [standalone]


#71352

FromAugust Karlstrom <fusionfile@gmail.com>
Date2015-09-28 08:18 +0200
Message-ID<muam44$f1t$1@speranza.aioe.org>
In reply to#71241
On 2015-09-27 01:16, Tim Rentsch wrote:
> August Karlstrom <fusionfile@gmail.com> writes:
>>> On 2015-09-10, August Karlstrom wrote:
>>>>> August Karlstrom <fusionfile@gmail.com> writes:
>>>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>>>>
>>>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>>>>
>>>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
[...]
>> I'm thinking that the macro NEW is semantically a function call
>> *statement*.

> That seems odd to me (talking just about the expressions part,
> not the declarations part).  I can see not wanting to make the
> value available, like a (void) function, but not restricted
> to just being a statement.  Or am I not understanding you?

I have no use case where using NEW as a statement will not do.


-- August

[toc] | [prev] | [next] | [standalone]


#71240

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-26 16:10 -0700
Message-ID<kfnwpvceq0h.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71161
Philip Lantz <prl@canterey.us> writes:

> On 2015-09-10, August Karlstrom wrote:
>> On 2015-09-09 19:22, Tim Rentsch wrote:
>>> August Karlstrom <fusionfile@gmail.com> writes:
>>>> #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
>>>>
>>>> #define NEW_ARRAY(ptr, n) (ptr) = malloc((n) * sizeof *(ptr))
>>>>
>>>> #define NEW(ptr) NEW_ARRAY((ptr), 1)
>>>
>>> Incidentally, you probably know this, but these NEW's can be
>>> used as parts of declarations:
>>>
>>> int *NEW( stuff, 20 );
>>
>> Or "misused", depending on how you see it. ;-)
>
> Perhaps Tim was slyly pointing out that you omitted the usual
> parentheses around the macro expansion.
>
> Oh, I see from his next response that he probably wasn't.  But
> fully parenthesizing macros that expand to expressions is
> generally considered good form, and it would prevent the "misuse",
> should you care to do so.

Here is the problem.  I would like a macro, or set of macros,
that can be used for (safe) allocation, and to be able to
make use of such macros also in declarations with initializers.
What is a reasonable way to do that?  Note that I want to
cover the case where the pointer being declared is const,
eg,

    struct foo *const ...

[toc] | [prev] | [next] | [standalone]


#71285

Fromsupercat@casperkitty.com
Date2015-09-27 11:40 -0700
Message-ID<23402522-0282-4dd1-bf74-7352ccdde3db@googlegroups.com>
In reply to#71240
On Saturday, September 26, 2015 at 6:10:15 PM UTC-5, Tim Rentsch wrote:
> Here is the problem.  I would like a macro, or set of macros,
> that can be used for (safe) allocation, and to be able to
> make use of such macros also in declarations with initializers.
> What is a reasonable way to do that?  Note that I want to
> cover the case where the pointer being declared is const,
> eg,
> 
>     struct foo *const ...

For macros which only need to operate at a place where a new identifier can
be declared, give the macro the name of an identifier to create.  For example,
someone using my style of prefixed string could set up macros such that:

  CONST_TSTR(foo, "George");
  CONST_MSTR(bar, [ some 1234-character string ] );
  LSTR_BUFF(boz, 16384);

  ...
  LSTR_INIT(boz); /* Must go after initializations */

would effectively yield

  struct { 
     union { unsigned char short_length, unsigned char st[1];} st;
     char dat[6];
  } foo = { { ENC_TINY_LENGTH(6) }, "George" };

  struct { 
     union { unsigned short med_length, unsigned char st[1];} st;
     char dat[1234];
  } bar = { { ENC_MED_LENGTH(1234) }, [ some 1234-character string ] };

  struct { 
     union { unsigned long long_length, unsigned char st[1];} st;
     char dat[16384];
  } boz;

  ...

  /* Mark boz as an initially-empty string buffer of length 16384 */

  boz.long_length = ENC_LONG_IBUFF_LENGTH( sizeof boz.dat );

and one could pass the `st.st` member of any of the strings to any function
that was designed to handle prefixed strings.  I don't think there's any way
to have a macro auto-select the storage layout based upon the string length,
but a macro could be written to squawk if one attempts to initialize a tiny
string with a literal that's more than 63 characters long or a medium string
more than 4095 characters long.

[toc] | [prev] | [next] | [standalone]


#71438

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-29 10:03 -0700
Message-ID<kfnd1x1cg4x.fsf@x-alumni2.alumni.caltech.edu>
In reply to#71285
supercat@casperkitty.com writes:

> On Saturday, September 26, 2015 at 6:10:15 PM UTC-5, Tim Rentsch wrote:
>> Here is the problem.  I would like a macro, or set of macros,
>> that can be used for (safe) allocation, and to be able to
>> make use of such macros also in declarations with initializers.
>> What is a reasonable way to do that?  Note that I want to
>> cover the case where the pointer being declared is const,
>> eg,
>>
>>     struct foo *const ...
>
> For macros which only need to operate at a place where a new identifier can
> be declared, give the macro the name of an identifier to create.  For example,
> someone using my style of prefixed string could set up macros such that:
>
>   CONST_TSTR(foo, "George");
>   CONST_MSTR(bar, [ some 1234-character string ] );
>   LSTR_BUFF(boz, 16384);
>
>   ...
>   LSTR_INIT(boz); /* Must go after initializations */
>
> would effectively yield
>
>   struct { 
>      union { unsigned char short_length, unsigned char st[1];} st;
>      char dat[6];
>   } foo = { { ENC_TINY_LENGTH(6) }, "George" };
>
>   struct { 
>      union { unsigned short med_length, unsigned char st[1];} st;
>      char dat[1234];
>   } bar = { { ENC_MED_LENGTH(1234) }, [ some 1234-character string ] };
>
>   struct { 
>      union { unsigned long long_length, unsigned char st[1];} st;
>      char dat[16384];
>   } boz;
>
>   ...
>
>   /* Mark boz as an initially-empty string buffer of length 16384 */
>
>   boz.long_length = ENC_LONG_IBUFF_LENGTH( sizeof boz.dat );
>
> and one could pass the `st.st` member of any of the strings to any function
> that was designed to handle prefixed strings.  I don't think there's any way
> to have a macro auto-select the storage layout based upon the string length,
> but a macro could be written to squawk if one attempts to initialize a tiny
> string with a literal that's more than 63 characters long or a medium string
> more than 4095 characters long.

Note that this has nothing to do with the question I was asking.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web