Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #70056 > unrolled thread
| Started by | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| First post | 2015-09-09 10:22 -0700 |
| Last post | 2015-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.
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
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-09-09 10:22 -0700 |
| Subject | Re: 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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Philip Lantz <prl@canterey.us> |
|---|---|
| Date | 2015-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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