Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #102281 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2017-01-21 08:52 -0800 |
| Last post | 2017-01-23 07:08 -0800 |
| Articles | 20 on this page of 55 — 11 participants |
Back to article view | Back to comp.lang.c
Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-21 08:52 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-21 09:35 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-21 10:28 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-21 23:49 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 00:29 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 10:54 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 03:28 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Keith Thompson <kst-u@mib.org> - 2017-01-22 07:44 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 08:24 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-22 10:43 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Keith Thompson <kst-u@mib.org> - 2017-01-22 12:22 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-22 11:33 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 13:23 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-22 13:28 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Keith Thompson <kst-u@mib.org> - 2017-01-22 07:47 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-22 16:00 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? David Brown <david.brown@hesbynett.no> - 2017-01-22 18:23 +0100
Re: Optimizing the code: way to reduce if, else if-s within the loop? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-22 13:47 -0500
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-22 10:43 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-22 13:53 -0500
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 18:57 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-22 19:18 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 21:54 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 02:41 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-23 11:20 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 03:53 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-23 12:12 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 03:24 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-22 13:16 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-22 07:47 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 08:16 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? "James R. Kuyper" <jameskuyper@verizon.net> - 2017-01-22 11:54 -0500
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 11:23 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-22 11:08 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 22:19 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 22:41 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Robert Wessel <robertwessel2@yahoo.com> - 2017-01-23 02:17 -0600
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-23 02:16 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 03:59 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Keith Thompson <kst-u@mib.org> - 2017-01-23 08:44 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 08:23 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-22 07:52 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-22 08:17 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Richard Heathfield <rjh@cpax.org.uk> - 2017-01-23 17:11 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 10:35 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 10:38 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-23 19:06 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Barry Schwarz <schwarzb@dqel.com> - 2017-01-23 14:31 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-23 21:31 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Alla _ <modelling.data@gmail.com> - 2017-01-24 01:56 -0800
Re: Optimizing the code: way to reduce if, else if-s within the loop? Manfred <noname@invalid.add> - 2017-01-24 14:38 +0100
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-24 13:57 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? BartC <bc@freeuk.com> - 2017-01-23 12:38 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-23 15:08 +0000
Re: Optimizing the code: way to reduce if, else if-s within the loop? m.labanowicz@gmail.com - 2017-01-23 07:08 -0800
Page 1 of 3 [1] 2 3 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 08:52 -0800 |
| Subject | Optimizing the code: way to reduce if, else if-s within the loop? |
| Message-ID | <a7575c18-3cd0-427c-bfc3-0285b5770cb6@googlegroups.com> |
Hello!
Please, take a look at this small function that parses numbers from
a line, and stores values in respective members of a respective
structure, which is a part of an array of structures.
I pass the row name to this function to determine which member
of the array should be populated. The problem I see here: the function
has to compare the name, which it gets from another function, to the
name in the line, and only then parse the number into the respective
member of the structure; but for now this comparison happens within
each iteration of the while loop, which is so inefficient. Is it possible
to avoid this inefficiency? I was thinking of creating a separate function
and move all these if-s there, and make this function return a certain
structure member. But will I be able to populate it if structure members
can be accessed only by direct name?
/** Function to parse numbers from each line **/
bool parse_numbers(char *line, struct data *dat_years, char *name)
{
char *ptr = line;
char *not_converted = NULL;
int count = 0;
while(count < DATA_SIZE)
{
if(!strcmp(name, "Sales"))
dat_years->sales = strtod(ptr, ¬_converted);
else if (!strcmp(name, "Cost of Goods Sold") ||
!strcmp(name, "COGS") )
dat_years->cs_cogs = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Gross Profit"))
dat_years->cs_gross_profit = strtod(ptr, ¬_converted);
else if (!strcmp(name, "\"Selling, General, and Admin Exp\"") ||
!strcmp(name, "SG&A") )
dat_years->cs_sga = strtod(ptr, ¬_converted);
else if (!strcmp(name, "Operating Income before Depr") ||
!strcmp(name, "Operating Income before Depreciation") )
dat_years->cs_oper_inc = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Depreciation and Amortization"))
dat_years->cs_dep_amor = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Operating Profit"))
dat_years->cs_oper_prof = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Interest Expense"))
dat_years->cs_int_exp = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Other Gains and Losses"))
dat_years->cs_gain_loss = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Pretax Income"))
dat_years->cs_pretax_inc = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Income Tax Expense"))
dat_years->cs_tax_exp = strtod(ptr, ¬_converted);
else if(!strcmp(name, "Net Income"))
dat_years->cs_net_inc = strtod(ptr, ¬_converted);
if (not_converted > ptr)
{
count++;
dat_years += (count != DATA_SIZE);
ptr = not_converted + (*not_converted != '\0');
}
else
{
fprintf(stderr, "Incorrect data on line %s at count %i\n", line, count);
return false;
}
}
return count == DATA_SIZE;
}
Thank you!
[toc] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 09:35 -0800 |
| Message-ID | <882d981e-f937-46c0-9646-e36180627d6f@googlegroups.com> |
| In reply to | #102281 |
On Saturday, January 21, 2017 at 7:52:31 PM UTC+3, Alla _ wrote: I have forgotten to mention that I need to determine the member of the structure a few times, because there is a part where I need to extract numbers and process them. Using this huge if-else if construction a few times within a program sounds inefficient, but I don't yet see another way. Please, if there is a way, give me hint - a hint, not a solution ) Thank you!
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-01-21 10:28 -0800 |
| Message-ID | <pl678c5imu0sajbmj8lejvlik9hm1snkcg@4ax.com> |
| In reply to | #102281 |
On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _
<modelling.data@gmail.com> wrote:
>Hello!
>
>Please, take a look at this small function that parses numbers from
>a line, and stores values in respective members of a respective
>structure, which is a part of an array of structures.
>I pass the row name to this function to determine which member
>of the array should be populated. The problem I see here: the function
NO. You pass the row name to determine which member of the struct
should be populated. Which element of the array you populate changes
with each iteration of your while loop. If day_years starts by
pointing to element 0 of the array, you first populate the designated
member of element 0, then you populate the corresponding member in
element 1, etc, until you finally populate that member of element
DATA_SIZE-1.
>has to compare the name, which it gets from another function, to the
>name in the line, and only then parse the number into the respective
>member of the structure; but for now this comparison happens within
>each iteration of the while loop, which is so inefficient. Is it possible
>to avoid this inefficiency? I was thinking of creating a separate function
>and move all these if-s there, and make this function return a certain
>structure member. But will I be able to populate it if structure members
>can be accessed only by direct name?
There are at least two solutions to this problem. First, recognize
that the results of each call to strcmp never change no matter how
many times you iterate the while loop. That is a strong hint that
those calls should not be in the loop but should precede it. In
contract, the calls to strtod do result in different results so those
should be in the loop. So the question becomes: how do we pass the
single true result from strncmp to the code inside the loop.
Method 1: Change the processing for each if to
int member;
if(!strcmp(name, "Sales"))
member = 1;
else if (!strcmp(name, "Cost of Goods Sold") ||
!strcmp(name, "COGS") )
member = 2;
etc
and move it just before the while statement. (Don't forget the error
logic also.) Inside the loop, use a switch statement of the form
switch (member)
{
case 1:
dat_years->sales = strtod(ptr, ¬_converted);
break;
case 2:
dat_years->cs_cogs = strtod(ptr, ¬_converted);
break;
etc
)
(Depending on your compiler, a switch statement may be more efficient
than the corresponding if-else logic. But you could use the
equivalent if member == 1 then .. else if member == 2 then ...)
Method 2: If your system supports the offsetof macro and if you
change some of the numeric members so they are all double, you could
change method 1 to
int offset;
if(!strcmp(name, "Sales"))
offset = offsetof(struct data, sales);
else if (!strcmp(name, "Cost of Goods Sold") ||
offset = offsetof(struct data, cs_cogs);
etc
and inside the loop you need only one assignment
*(double*)((char*)dat_years + offset) = strtod(...);
>/** Function to parse numbers from each line **/
>bool parse_numbers(char *line, struct data *dat_years, char *name)
>{
> char *ptr = line;
> char *not_converted = NULL;
> int count = 0;
>
> while(count < DATA_SIZE)
> {
> if(!strcmp(name, "Sales"))
> dat_years->sales = strtod(ptr, ¬_converted);
>
> else if (!strcmp(name, "Cost of Goods Sold") ||
> !strcmp(name, "COGS") )
> dat_years->cs_cogs = strtod(ptr, ¬_converted);
Why are you using strtod here when your members (other than sales) are
int? Do you have something against strtol? Does your data contain
decimal points and you are truncating the values?
> else if(!strcmp(name, "Gross Profit"))
> dat_years->cs_gross_profit = strtod(ptr, ¬_converted);
>
> else if (!strcmp(name, "\"Selling, General, and Admin Exp\"") ||
> !strcmp(name, "SG&A") )
> dat_years->cs_sga = strtod(ptr, ¬_converted);
>
> else if (!strcmp(name, "Operating Income before Depr") ||
> !strcmp(name, "Operating Income before Depreciation") )
> dat_years->cs_oper_inc = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Depreciation and Amortization"))
> dat_years->cs_dep_amor = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Operating Profit"))
> dat_years->cs_oper_prof = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Interest Expense"))
> dat_years->cs_int_exp = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Other Gains and Losses"))
> dat_years->cs_gain_loss = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Pretax Income"))
> dat_years->cs_pretax_inc = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Income Tax Expense"))
> dat_years->cs_tax_exp = strtod(ptr, ¬_converted);
>
> else if(!strcmp(name, "Net Income"))
> dat_years->cs_net_inc = strtod(ptr, ¬_converted);
If the line is malformed, none of the if expressions evaluate to true
so strtod is never called and not_converted still has the value NULL.
>
> if (not_converted > ptr)
A pointer comparison expression (other than equality/inequality) such
as this is legal only if both pointers point within or exactly one
byte past the end of the same array. If not_converted is NULL, this
is not true. This produces undefined behavior.
The simplest way to avoid this problem is to set not_converted to ptr
in its initialization at the top of the function
> {
> count++;
> dat_years += (count != DATA_SIZE);
> ptr = not_converted + (*not_converted != '\0');
> }
> else
> {
> fprintf(stderr, "Incorrect data on line %s at count %i\n", line, count);
> return false;
> }
> }
>
> return count == DATA_SIZE;
>}
>
>Thank you!
--
Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-21 23:49 -0800 |
| Message-ID | <a60a0244-017a-4240-878e-e09764f33d29@googlegroups.com> |
| In reply to | #102295 |
On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote:
> On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _
> <modelling.data@gmail.com> wrote:
>
> >Hello!
> >
> >Please, take a look at this small function that parses numbers from
> >a line, and stores values in respective members of a respective
> >structure, which is a part of an array of structures.
> >I pass the row name to this function to determine which member
> >of the array should be populated. The problem I see here: the function
>
> NO. You pass the row name to determine which member of the struct
> should be populated. Which element of the array you populate changes
> with each iteration of your while loop. If day_years starts by
> pointing to element 0 of the array, you first populate the designated
> member of element 0, then you populate the corresponding member in
> element 1, etc, until you finally populate that member of element
> DATA_SIZE-1.
Yes, that is exactly what I do with this code.
>
> >has to compare the name, which it gets from another function, to the
> >name in the line, and only then parse the number into the respective
> >member of the structure; but for now this comparison happens within
> >each iteration of the while loop, which is so inefficient. Is it possible
> >to avoid this inefficiency? I was thinking of creating a separate function
> >and move all these if-s there, and make this function return a certain
> >structure member. But will I be able to populate it if structure members
> >can be accessed only by direct name?
>
> There are at least two solutions to this problem. First, recognize
> that the results of each call to strcmp never change no matter how
> many times you iterate the while loop. That is a strong hint that
> those calls should not be in the loop but should precede it.
Yes, this is the main reason I asked about this issue. I am reading on,
just jumping in with some comments.
> In
> contract, the calls to strtod do result in different results so those
> should be in the loop. So the question becomes: how do we pass the
> single true result from strncmp to the code inside the loop.
>
> Method 1: Change the processing for each if to
> int member;
> if(!strcmp(name, "Sales"))
> member = 1;
> else if (!strcmp(name, "Cost of Goods Sold") ||
> !strcmp(name, "COGS") )
> member = 2;
> etc
> and move it just before the while statement. (Don't forget the error
> logic also.) Inside the loop, use a switch statement of the form
> switch (member)
> {
> case 1:
> dat_years->sales = strtod(ptr, ¬_converted);
> break;
> case 2:
> dat_years->cs_cogs = strtod(ptr, ¬_converted);
> break;
> etc
> )
Thank you so much! I was thinking of doing something of this sort
using switch. I have also created a new separate function for this
purpose - a function that should return something (now it will be
a member variable); but I didn't see how to use those members with
calls to strode. I see it now.
> (Depending on your compiler, a switch statement may be more efficient
> than the corresponding if-else logic. But you could use the
> equivalent if member == 1 then .. else if member == 2 then ...)
>
> Method 2: If your system supports the offsetof macro and if you
> change some of the numeric members so they are all double, you could
> change method 1 to
> int offset;
> if(!strcmp(name, "Sales"))
> offset = offsetof(struct data, sales);
> else if (!strcmp(name, "Cost of Goods Sold") ||
> offset = offsetof(struct data, cs_cogs);
> etc
> and inside the loop you need only one assignment
> *(double*)((char*)dat_years + offset) = strtod(...);
>
Thank you very much - this is so much better. I will now
learn more about this type of usage, and see if I can use
it on my machine. And, as said above, I will move this to
a separate function.
> >/** Function to parse numbers from each line **/
> >bool parse_numbers(char *line, struct data *dat_years, char *name)
> >{
> > char *ptr = line;
> > char *not_converted = NULL;
> > int count = 0;
> >
> > while(count < DATA_SIZE)
> > {
> > if(!strcmp(name, "Sales"))
> > dat_years->sales = strtod(ptr, ¬_converted);
> >
> > else if (!strcmp(name, "Cost of Goods Sold") ||
> > !strcmp(name, "COGS") )
> > dat_years->cs_cogs = strtod(ptr, ¬_converted);
>
> Why are you using strtod here when your members (other than sales) are
> int?
No, they are doubles now; ints were in the test version; I have changed
them to doubles, because eventually they will store not the data
saved from the line, but already processed one. I will show that later.
>Do you have something against strtol? Does your data contain
> decimal points and you are truncating the values?
>
> > else if(!strcmp(name, "Gross Profit"))
> > dat_years->cs_gross_profit = strtod(ptr, ¬_converted);
> >
> > else if (!strcmp(name, "\"Selling, General, and Admin Exp\"") ||
> > !strcmp(name, "SG&A") )
> > dat_years->cs_sga = strtod(ptr, ¬_converted);
> >
> > else if (!strcmp(name, "Operating Income before Depr") ||
> > !strcmp(name, "Operating Income before Depreciation") )
> > dat_years->cs_oper_inc = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Depreciation and Amortization"))
> > dat_years->cs_dep_amor = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Operating Profit"))
> > dat_years->cs_oper_prof = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Interest Expense"))
> > dat_years->cs_int_exp = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Other Gains and Losses"))
> > dat_years->cs_gain_loss = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Pretax Income"))
> > dat_years->cs_pretax_inc = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Income Tax Expense"))
> > dat_years->cs_tax_exp = strtod(ptr, ¬_converted);
> >
> > else if(!strcmp(name, "Net Income"))
> > dat_years->cs_net_inc = strtod(ptr, ¬_converted);
>
> If the line is malformed, none of the if expressions evaluate to true
> so strtod is never called and not_converted still has the value NULL.
> >
> > if (not_converted > ptr)
>
> A pointer comparison expression (other than equality/inequality) such
> as this is legal only if both pointers point within or exactly one
> byte past the end of the same array. If not_converted is NULL, this
> is not true. This produces undefined behavior.
>
> The simplest way to avoid this problem is to set not_converted to ptr
> in its initialization at the top of the function
Oh, I see. Indeed. Done. I have to revisit other parts, where I have
the same type of code, as well now.
>
<snip>
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-22 00:29 -0800 |
| Message-ID | <35c56d5c-ff4a-46b5-9166-e88353bf62ce@googlegroups.com> |
| In reply to | #102295 |
On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote: > On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _ > <modelling.data@gmail.com> wrote: <snip> > Method 2: If your system supports the offsetof macro and if you > change some of the numeric members so they are all double, you could > change method 1 to > int offset; > if(!strcmp(name, "Sales")) > offset = offsetof(struct data, sales); > else if (!strcmp(name, "Cost of Goods Sold") || > offset = offsetof(struct data, cs_cogs); > etc > and inside the loop you need only one assignment > *(double*)((char*)dat_years + offset) = strtod(...); > <snip> Reading some resources, I have found this phrase (repeated a few times) on stackoverflow: "this code is not advised when using a modern C compiler." Does it mean that it is not safe to use it, and that this code will limit the usage of the program? I still have to dig much deeper into details, but I have saved those materials for later study (I have to revisit the padding issue, etc, but I assume offsetof() helps to avoid the padding - anyway, I would not like to get into this topic now).
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-22 10:54 +0000 |
| Message-ID | <o62392$ho0$1@dont-email.me> |
| In reply to | #102309 |
Alla _ <modelling.data@gmail.com> writes:
> On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote:
>> On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _
>> <modelling.data@gmail.com> wrote:
> <snip>
>> Method 2: If your system supports the offsetof macro and if you
A C implementation without offsetof is not conforming. It's a part of
the language you can rely on being there.
>> change some of the numeric members so they are all double, you could
>> change method 1 to
>> int offset;
>> if(!strcmp(name, "Sales"))
>> offset = offsetof(struct data, sales);
>> else if (!strcmp(name, "Cost of Goods Sold") ||
>> offset = offsetof(struct data, cs_cogs);
>> etc
>> and inside the loop you need only one assignment
>> *(double*)((char*)dat_years + offset) = strtod(...);
>>
> <snip>
> Reading some resources, I have found this phrase (repeated a few
> times) on stackoverflow: "this code is not advised when using a modern
> C compiler." Does it mean that it is not safe to use it, and that
> this code will limit the usage of the program?
It could mean that. It could also mean the writer is wrong. Equally,
they could be correct but about slightly different code.
> I still have to
> dig much deeper into details, but I have saved those materials for
> later study (I have to revisit the padding issue, etc, but I assume
> offsetof() helps to avoid the padding - anyway, I would not like to
> get into this topic now).
Other than being a bit ugly there is nothing wrong with the code above
and there is certainly no problem with padding.
But I would go another way. Rather than find the offset of a named
member, I'd make all the members have numbers and name the numbers.
I.e. instead of
struct data {
double sales;
double cs_cogs;
...
};
I'd write
enum {
Sales,
CS_Cogs,
...
NumberOfItems
}; /* or use a list of #define lines */
struct data {
double item[NumberOfItems];
};
Now you can have the names in a table and simply look up the
corresponding number.
const char *names[] = {
[Sales] = "Sales",
[CS_Cogs] = "Cost of Goods Sold",
...
};
Now you would loop through the array looking for the name you have.
When you find it at position x, you store the data in item[x].
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-22 03:28 -0800 |
| Message-ID | <ff3dd001-6d6c-4632-9d9a-fac82d60e000@googlegroups.com> |
| In reply to | #102310 |
On Sunday, January 22, 2017 at 2:00:32 PM UTC+3, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
>
<snip>
> But I would go another way. Rather than find the offset of a named
> member, I'd make all the members have numbers and name the numbers.
> I.e. instead of
>
> struct data {
> double sales;
> double cs_cogs;
> ...
> };
>
> I'd write
>
> enum {
> Sales,
> CS_Cogs,
> ...
> NumberOfItems
> }; /* or use a list of #define lines */
>
> struct data {
> double item[NumberOfItems];
> };
>
> Now you can have the names in a table and simply look up the
> corresponding number.
>
> const char *names[] = {
> [Sales] = "Sales",
> [CS_Cogs] = "Cost of Goods Sold",
> ...
> };
>
> Now you would loop through the array looking for the name you have.
> When you find it at position x, you store the data in item[x].
Thank you very much! I will implement this.
But as I have spent quite a while trying to implement offsetof(), I would like
to finish that one too, to find my mistakes, correct them and make the code
work.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-22 07:44 -0800 |
| Message-ID | <lnpojff69y.fsf@kst-u.example.com> |
| In reply to | #102313 |
Alla _ <modelling.data@gmail.com> writes:
[...]
> But as I have spent quite a while trying to implement offsetof(), I
> would like to finish that one too, to find my mistakes, correct them
> and make the code work.
Are you trying to *implement* offsetof(), or are you trying to *use*
offsetof()?
If you're trying to implement it (i.e., write your own version), then
(a) it's not necessary, since all conforming C implementations provide
it in <stddef.h>, and (b) there is no completely portable way to
implement it (which is part of why it's defined in the standard
library).
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2017-01-22 08:24 -0800 |
| Message-ID | <6f0ce458-5b19-4c11-b1be-2e24160156a6@googlegroups.com> |
| In reply to | #102326 |
On Sunday, January 22, 2017 at 6:43:59 PM UTC+3, Keith Thompson wrote: > Alla _ <modelling.data@gmail.com> writes: > [...] > > But as I have spent quite a while trying to implement offsetof(), I > > would like to finish that one too, to find my mistakes, correct them > > and make the code work. > > Are you trying to *implement* offsetof(), or are you trying to *use* > offsetof()? Oh, no, of course not to implement, i.e. write it myself, but to use it. Apologies for using the wrong word. > > If you're trying to implement it (i.e., write your own version), then > (a) it's not necessary, since all conforming C implementations provide > it in <stddef.h>, and (b) there is no completely portable way to > implement it (which is part of why it's defined in the standard > library). > > -- > Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst> > Working, but not speaking, for JetHead Development, Inc. > "We must do something. This is something. Therefore, we must do this." > -- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-01-22 10:43 -0800 |
| Message-ID | <9av98ct6js5521njh31edq5kvnm6eqok53@4ax.com> |
| In reply to | #102326 |
>If you're trying to implement it (i.e., write your own version), then >(a) it's not necessary, since all conforming C implementations provide >it in <stddef.h>, and (b) there is no completely portable way to >implement it (which is part of why it's defined in the standard >library). Of course you meant standard header, not library. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-22 12:22 -0800 |
| Message-ID | <ln60l6g807.fsf@kst-u.example.com> |
| In reply to | #102347 |
Barry Schwarz <schwarzb@dqel.com> writes:
>>If you're trying to implement it (i.e., write your own version), then
>>(a) it's not necessary, since all conforming C implementations provide
>>it in <stddef.h>, and (b) there is no completely portable way to
>>implement it (which is part of why it's defined in the standard
>>library).
>
> Of course you meant standard header, not library.
Yes, "standard header" would have been more precise. (On the other
hand, it's specified in the "Library" section of the standard,
which is what I meant to refer to.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-22 11:33 +0000 |
| Message-ID | <o6256j$nou$1@dont-email.me> |
| In reply to | #102310 |
On 22/01/2017 10:54, Ben Bacarisse wrote: > Alla _ <modelling.data@gmail.com> writes: > >> On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote: >>> On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _ >>> <modelling.data@gmail.com> wrote: >> <snip> >>> Method 2: If your system supports the offsetof macro and if you > > A C implementation without offsetof is not conforming. It's a part of > the language you can rely on being there. This seems a common way of implementing it: #define offsetof(s,m) (int)&(((s *)0)->m) or: #define offsetof(t,i) ((size_t)((char *)&((t *)0)->i - (char *)0)) So I don't think anyone would be stuck for such a macro. (gcc of course has to be a little different, with offsetof being a synonym for __builtin_offsetof.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-22 13:23 +0000 |
| Message-ID | <87efzvxm7h.fsf@bsb.me.uk> |
| In reply to | #102314 |
BartC <bc@freeuk.com> writes: > On 22/01/2017 10:54, Ben Bacarisse wrote: >> Alla _ <modelling.data@gmail.com> writes: >> >>> On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote: >>>> On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _ >>>> <modelling.data@gmail.com> wrote: >>> <snip> >>>> Method 2: If your system supports the offsetof macro and if you >> >> A C implementation without offsetof is not conforming. It's a part of >> the language you can rely on being there. > > This seems a common way of implementing it: > > #define offsetof(s,m) (int)&(((s *)0)->m) That would be wrong so I'm sorry to hear it's a common way. > or: > > #define offsetof(t,i) ((size_t)((char *)&((t *)0)->i - (char *)0)) > > So I don't think anyone would be stuck for such a macro. You should not be stuck for such a macro because it's part of standard C! It's just a distraction to suggest there might be some problem with it. It's been in C for more than 27 years. > (gcc of course has to be a little different, with offsetof being a > synonym for __builtin_offsetof.) The implementations you show are not portable and gcc is not limited to working on one architecture. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-22 13:28 +0000 |
| Message-ID | <o62bvj$ma5$1@dont-email.me> |
| In reply to | #102318 |
On 22/01/2017 13:23, Ben Bacarisse wrote: > BartC <bc@freeuk.com> writes: > >> On 22/01/2017 10:54, Ben Bacarisse wrote: >>> Alla _ <modelling.data@gmail.com> writes: >>> >>>> On Saturday, January 21, 2017 at 9:28:19 PM UTC+3, Barry Schwarz wrote: >>>>> On Sat, 21 Jan 2017 08:52:25 -0800 (PST), Alla _ >>>>> <modelling.data@gmail.com> wrote: >>>> <snip> >>>>> Method 2: If your system supports the offsetof macro and if you >>> >>> A C implementation without offsetof is not conforming. It's a part of >>> the language you can rely on being there. >> >> This seems a common way of implementing it: >> >> #define offsetof(s,m) (int)&(((s *)0)->m) > > That would be wrong so I'm sorry to hear it's a common way. What's wrong with it? -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-01-22 07:47 -0800 |
| Message-ID | <lnlgu3f669.fsf@kst-u.example.com> |
| In reply to | #102320 |
BartC <bc@freeuk.com> writes:
> On 22/01/2017 13:23, Ben Bacarisse wrote:
>> BartC <bc@freeuk.com> writes:
[...]
>>> This seems a common way of implementing it:
>>>
>>> #define offsetof(s,m) (int)&(((s *)0)->m)
>>
>> That would be wrong so I'm sorry to hear it's a common way.
>
> What's wrong with it?
offsetof yields a result of type size_t. This macro yields a result of
type int. (It's also non-portable, but in a way that's likely to work
under most implementations.)
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-22 16:00 +0000 |
| Message-ID | <o62kre$sc7$1@dont-email.me> |
| In reply to | #102327 |
On 22/01/2017 15:47, Keith Thompson wrote: > BartC <bc@freeuk.com> writes: >> On 22/01/2017 13:23, Ben Bacarisse wrote: >>> BartC <bc@freeuk.com> writes: > [...] >>>> This seems a common way of implementing it: >>>> >>>> #define offsetof(s,m) (int)&(((s *)0)->m) >>> >>> That would be wrong so I'm sorry to hear it's a common way. >> >> What's wrong with it? > > offsetof yields a result of type size_t. This macro yields a result of > type int. (It's also non-portable, but in a way that's likely to work > under most implementations.) Well, some use size_t in the cast, but this version came from a 32-bit compiler so was probably OK. But as I understand it, if size_t was needed and int was used, then it would go wrong with structs of more than 2GB or so, and then only if the member of interest was past that 2GB? -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-22 18:23 +0100 |
| Message-ID | <o62pnf$brk$2@dont-email.me> |
| In reply to | #102333 |
On 22/01/17 17:00, BartC wrote: > On 22/01/2017 15:47, Keith Thompson wrote: >> BartC <bc@freeuk.com> writes: >>> On 22/01/2017 13:23, Ben Bacarisse wrote: >>>> BartC <bc@freeuk.com> writes: >> [...] >>>>> This seems a common way of implementing it: >>>>> >>>>> #define offsetof(s,m) (int)&(((s *)0)->m) >>>> >>>> That would be wrong so I'm sorry to hear it's a common way. >>> >>> What's wrong with it? >> >> offsetof yields a result of type size_t. This macro yields a result of >> type int. (It's also non-portable, but in a way that's likely to work >> under most implementations.) > > Well, some use size_t in the cast, but this version came from a 32-bit > compiler so was probably OK. > > But as I understand it, if size_t was needed and int was used, then it > would go wrong with structs of more than 2GB or so, and then only if the > member of interest was past that 2GB? > Yes, except in cases where the type matters. On a 64-bit system, sizeo(offsetof(s, m)) is going to give different results with the "int" case and a "size_t" cast, and it will similarly affect other expressions where the type makes a difference.
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-01-22 13:47 -0500 |
| Message-ID | <2a3738a2-fabf-29a9-2e0d-ff69cbc56f46@verizon.net> |
| In reply to | #102342 |
On 01/22/2017 12:23 PM, David Brown wrote: > On 22/01/17 17:00, BartC wrote: >> On 22/01/2017 15:47, Keith Thompson wrote: >>> BartC <bc@freeuk.com> writes: >>>> On 22/01/2017 13:23, Ben Bacarisse wrote: >>>>> BartC <bc@freeuk.com> writes: >>> [...] >>>>>> This seems a common way of implementing it: >>>>>> >>>>>> #define offsetof(s,m) (int)&(((s *)0)->m) >>>>> >>>>> That would be wrong so I'm sorry to hear it's a common way. >>>> >>>> What's wrong with it? >>> >>> offsetof yields a result of type size_t. This macro yields a result of >>> type int. (It's also non-portable, but in a way that's likely to work >>> under most implementations.) >> >> Well, some use size_t in the cast, but this version came from a 32-bit >> compiler so was probably OK. >> >> But as I understand it, if size_t was needed and int was used, then it >> would go wrong with structs of more than 2GB or so, and then only if the >> member of interest was past that 2GB? > > Yes, except in cases where the type matters. On a 64-bit system, > sizeo(offsetof(s, m)) is going to give different results with the "int" > case and a "size_t" cast, and it will similarly affect other expressions > where the type makes a difference. Specifically, whether offsetof() has the type "int" or "size_t" will affect the usual arithmetic conversions (6.3.1.8).
[toc] | [prev] | [next] | [standalone]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2017-01-22 10:43 -0800 |
| Message-ID | <83v98cpbp4vmmt6gsv8da2imn4387kels3@4ax.com> |
| In reply to | #102333 |
On Sun, 22 Jan 2017 16:00:15 +0000, BartC <bc@freeuk.com> wrote: >On 22/01/2017 15:47, Keith Thompson wrote: >> BartC <bc@freeuk.com> writes: >>> On 22/01/2017 13:23, Ben Bacarisse wrote: >>>> BartC <bc@freeuk.com> writes: >> [...] >>>>> This seems a common way of implementing it: >>>>> >>>>> #define offsetof(s,m) (int)&(((s *)0)->m) >>>> >>>> That would be wrong so I'm sorry to hear it's a common way. >>> >>> What's wrong with it? >> >> offsetof yields a result of type size_t. This macro yields a result of >> type int. (It's also non-portable, but in a way that's likely to work >> under most implementations.) > >Well, some use size_t in the cast, but this version came from a 32-bit >compiler so was probably OK. > >But as I understand it, if size_t was needed and int was used, then it >would go wrong with structs of more than 2GB or so, and then only if the >member of interest was past that 2GB? Unless something has changed since C11, it is still compliant for an int to be only 16 bits. That puts the limit at 32K, a threshold more likely to be exceeded. -- Remove del for email
[toc] | [prev] | [next] | [standalone]
| From | "James R. Kuyper" <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-01-22 13:53 -0500 |
| Message-ID | <085e6c0d-2417-0803-bcdd-35565459901c@verizon.net> |
| In reply to | #102346 |
On 01/22/2017 01:43 PM, Barry Schwarz wrote: > On Sun, 22 Jan 2017 16:00:15 +0000, BartC <bc@freeuk.com> wrote: > >> On 22/01/2017 15:47, Keith Thompson wrote: >>> BartC <bc@freeuk.com> writes: >>>> On 22/01/2017 13:23, Ben Bacarisse wrote: >>>>> BartC <bc@freeuk.com> writes: >>> [...] >>>>>> This seems a common way of implementing it: >>>>>> >>>>>> #define offsetof(s,m) (int)&(((s *)0)->m) >>>>> >>>>> That would be wrong so I'm sorry to hear it's a common way. >>>> >>>> What's wrong with it? >>> >>> offsetof yields a result of type size_t. This macro yields a result of >>> type int. (It's also non-portable, but in a way that's likely to work >>> under most implementations.) >> >> Well, some use size_t in the cast, but this version came from a 32-bit >> compiler so was probably OK. >> >> But as I understand it, if size_t was needed and int was used, then it >> would go wrong with structs of more than 2GB or so, and then only if the >> member of interest was past that 2GB? > > Unless something has changed since C11, it is still compliant for an > int to be only 16 bits. That puts the limit at 32K, a threshold more > likely to be exceeded. My own code routinely exceeds that limit. It defines many different structs containing large arrays of data, most of which exceed that limit. We have an explicit waiver that allows us to exceed the 65535 minimum implementation limit on object sizes, compilers that allow us to exceed that limit, and machines where objects exceeding that limit don't cause any problems. In most ways, my code is subject to very strict portability requirements - but this is the main exception.
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web