Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #72251 > unrolled thread
| Started by | Alla _ <modelling.data@gmail.com> |
|---|---|
| First post | 2015-10-09 02:36 -0700 |
| Last post | 2015-11-05 15:50 -0800 |
| Articles | 20 on this page of 49 — 12 participants |
Back to article view | Back to comp.lang.c
Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 02:36 -0700
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-09 10:48 +0100
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 03:06 -0700
Re: Program to compute elapsed time, learning structures and functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-09 11:01 +0100
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 03:07 -0700
Re: Program to compute elapsed time, learning structures and functions Richard Heathfield <rjh@cpax.org.uk> - 2015-10-09 13:26 +0100
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 06:49 -0700
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-09 16:20 +0100
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 09:27 -0700
Re: Program to compute elapsed time, learning structures and functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-09 19:29 +0100
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-09 14:06 -0700
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-09 22:24 +0100
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-09 15:51 -0700
Re: Program to compute elapsed time, learning structures and functions Richard Heathfield <rjh@cpax.org.uk> - 2015-10-09 18:26 +0100
Re: Program to compute elapsed time, learning structures and functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-09 19:24 +0100
Re: Program to compute elapsed time, learning structures and functions Richard Heathfield <rjh@cpax.org.uk> - 2015-10-09 19:50 +0100
Re: Program to compute elapsed time, learning structures and functions Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-10-09 15:56 -0400
Re: Program to compute elapsed time, learning structures and functions James Kuyper <jameskuyper@verizon.net> - 2015-10-09 15:31 -0400
Re: Program to compute elapsed time, learning structures and functions Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-10 06:57 -0700
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-10 17:25 +0100
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-10 19:12 +0100
Re: Program to compute elapsed time, learning structures and functions Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-10-10 20:56 +0100
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-10 21:52 +0100
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-10 17:57 -0700
Re: Program to compute elapsed time, learning structures and functions raltbos@xs4all.nl (Richard Bos) - 2015-10-11 10:09 +0000
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-11 11:26 +0100
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-11 14:12 -0700
Re: Program to compute elapsed time, learning structures and functions Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-15 10:51 -0700
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-15 11:25 -0700
Re: Program to compute elapsed time, learning structures and functions Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-16 05:34 -0700
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-10-16 08:52 -0700
Re: Program to compute elapsed time, learning structures and functions Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-15 10:46 -0700
Re: Program to compute elapsed time, learning structures and functions Bartc <bc@freeuk.com> - 2015-10-15 19:06 +0100
Re: Program to compute elapsed time, learning structures and functions Tim Rentsch <txr@alumni.caltech.edu> - 2015-10-16 05:24 -0700
Re: Program to compute elapsed time, learning structures and functions glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-10-17 00:10 +0000
Re: Program to compute elapsed time, learning structures and functions Barry Schwarz <schwarzb@dqel.com> - 2015-10-18 09:52 -0700
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-10-09 06:52 -0700
Re: Program to compute elapsed time, learning structures and functions Barry Schwarz <schwarzb@dqel.com> - 2015-10-18 10:21 -0700
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 00:56 -0800
Re: Program to compute elapsed time, learning structures and functions Barry Schwarz <schwarzb@dqel.com> - 2015-11-05 01:55 -0800
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 02:55 -0800
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 03:01 -0800
Re: Program to compute elapsed time, learning structures and functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-05 03:41 -0800
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 06:55 -0800
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 03:03 -0800
Re: Program to compute elapsed time, learning structures and functions Richard Heathfield <rjh@cpax.org.uk> - 2015-11-05 13:27 +0000
Re: Program to compute elapsed time, learning structures and functions Alla _ <modelling.data@gmail.com> - 2015-11-05 06:54 -0800
Re: Program to compute elapsed time, learning structures and functions Keith Thompson <kst-u@mib.org> - 2015-11-05 12:42 -0800
Re: Program to compute elapsed time, learning structures and functions Malcolm McLean <malcolm.mclean5@btinternet.com> - 2015-11-05 15:50 -0800
Page 1 of 3 [1] 2 3 Next page →
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-09 02:36 -0700 |
| Subject | Program to compute elapsed time, learning structures and functions |
| Message-ID | <b151ca82-94b3-40ee-8444-2c0e61f5ed79@googlegroups.com> |
Hello!
Please, take a look at a small program that
should compute the elapsed time between two
times (based on a task from a textbook).
Please, cut me some slack for still using
scanf - it is only for educational purposes,
and I can't rush ahead through topics. Let's ignore
it for this moment. Thank you very much for
understanding.
Here is the error message I get when I try
to compile the program. I don't see why I get
this error message.
ex8-3.c: In function 'elapsed_time':
ex8-3.c:48: error: expected expression before '{' token
// Program to computed elapsed time between two times
#include <stdio.h>
struct time
{
int hour;
int minutes;
int seconds;
};
struct time elapsed_time (struct time time_1, struct time time_2);
int main (void)
{
struct time time_one, time_two, elapsed;
printf("Please, enter two times (hh:mm:ss): ");
scanf ("%i:%i:%i %i:%i:%i", &time_one.seconds, &time_one.minutes, &time_one.hour, &time_two.seconds, &time_two.minutes, &time_two.hour );
elapsed = elapsed_time (time_one, time_two);
printf("The elapsed time is %.2i:%.2i:%.2i\n", elapsed.hour, elapsed.minutes, elapsed.seconds);
return 0;
}
// Function to compute elapsed time
struct time elapsed_time (struct time time_1, struct time time_2)
{
struct time result;
if (time_2.seconds < time_1.seconds || time_2.minutes < time_1.minutes)
{
result.seconds = time_2.seconds - time_1.seconds + 60;
time_2.minutes--;
result.minutes = time_2.minutes - time_1.minutes + 60;
time_2.hour --;
result.hour = time_2.hour - time_1.hour;
}
if (time_2.hour < time_1.hour) // Time_2 is the next day, over 00:00:00
result.hour = 24 - time_2.hour + time_1.hour;
result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
return result;
}
Thank you!
[toc] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-09 10:48 +0100 |
| Message-ID | <mv82dn$vvq$1@dont-email.me> |
| In reply to | #72251 |
On 09/10/2015 10:36, Alla _ wrote:
> ex8-3.c: In function 'elapsed_time':
> ex8-3.c:48: error: expected expression before '{' token
> struct time result;
> result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
This might not be legal (not without complicated syntax involving
compound literals anyway).
Keep it simple:
result.hour = time_2.hour - time_1.hour;
result.minutes = time_2.minutes - time_1.minutes;
result.seconds = time_2.seconds - time_1.seconds;
(The program didn't work quite correctly, but that's something for you
to look at.)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-09 03:06 -0700 |
| Message-ID | <33796873-e6f1-4a7b-9daf-afc61d802228@googlegroups.com> |
| In reply to | #72253 |
On Friday, October 9, 2015 at 1:48:43 PM UTC+4, Bart wrote:
> On 09/10/2015 10:36, Alla _ wrote:
>
> > ex8-3.c: In function 'elapsed_time':
> > ex8-3.c:48: error: expected expression before '{' token
>
> > struct time result;
>
> > result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
>
> This might not be legal (not without complicated syntax involving
> compound literals anyway).
>
> Keep it simple:
>
> result.hour = time_2.hour - time_1.hour;
> result.minutes = time_2.minutes - time_1.minutes;
> result.seconds = time_2.seconds - time_1.seconds;
>
> (The program didn't work quite correctly, but that's something for you
> to look at.)
>
> --
> Bartc
Thank you! I will now try this. Though I don't see
why that approach didn't work. I've also tried
result = {time_2.hour - time_1.hour, time_2.minutes - time_1.minutes, .time_2.seconds - time_1.seconds};
and got the same error message.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-09 11:01 +0100 |
| Message-ID | <87zizsjr8d.fsf@bsb.me.uk> |
| In reply to | #72251 |
Alla _ <modelling.data@gmail.com> writes:
<snip>
> ex8-3.c: In function 'elapsed_time':
> ex8-3.c:48: error: expected expression before '{' token
<snip>
> struct time
> {
> int hour;
> int minutes;
> int seconds;
> };
<snip>
> struct time elapsed_time (struct time time_1, struct time time_2)
> {
<snip>
> result = {.hour = time_2.hour - time_1.hour,
> .minutes = time_2.minutes - time_1.minutes,
> .seconds = time_2.seconds - time_1.seconds};
You are missing the (struct time) part from the compound literal. The
syntax has a type in ()s and an initialiser in {}s.
> return result;
You might as well return the literal here rather than go to the bother
of giving it a name first. If you did that, it might show up something
else you need to look at in your function!
> }
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-09 03:07 -0700 |
| Message-ID | <b5ffbc99-f634-4fbb-a1d4-f64f03d4cbc6@googlegroups.com> |
| In reply to | #72254 |
On Friday, October 9, 2015 at 2:01:17 PM UTC+4, Ben Bacarisse wrote:
> Alla _ <modelling.data@gmail.com> writes:
> <snip>
> > ex8-3.c: In function 'elapsed_time':
> > ex8-3.c:48: error: expected expression before '{' token
> <snip>
> > struct time
> > {
> > int hour;
> > int minutes;
> > int seconds;
> > };
> <snip>
> > struct time elapsed_time (struct time time_1, struct time time_2)
> > {
> <snip>
> > result = {.hour = time_2.hour - time_1.hour,
> > .minutes = time_2.minutes - time_1.minutes,
> > .seconds = time_2.seconds - time_1.seconds};
>
> You are missing the (struct time) part from the compound literal. The
> syntax has a type in ()s and an initialiser in {}s.
>
> > return result;
>
> You might as well return the literal here rather than go to the bother
> of giving it a name first. If you did that, it might show up something
> else you need to look at in your function!
>
> > }
>
> --
> Ben.
Thank you! I thought that I don't need to add
additional (struct time) after =, because I
have declared result to be of a struct time type.
Will look into it again. Thank you.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-09 13:26 +0100 |
| Message-ID | <mv8bku$22a$1@dont-email.me> |
| In reply to | #72251 |
On 09/10/15 10:36, Alla _ wrote:
> Here is the error message I get when I try
> to compile the program. I don't see why I get
> this error message.
>
> ex8-3.c: In function 'elapsed_time':
> ex8-3.c:48: error: expected expression before '{' token
<snip>
> result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
It's complaining about .hour
Is there any particular reason why you can't write
result.hour = time_2.hour - time_1.hour;
result.minutes = time_2.minutes - time_1.minutes;
result.seconds = time_2.seconds - time_1.seconds;
?
It will compile, it's clearer, it requires less typing in a good editor,
and it makes the bug more obvious and far easier to fix.
And if you must use scanf (which I regard as an advanced function for
experts only, and I certainly don't consider myself expert enough to use
it with confidence), at the very least you should check the return value
to make sure that you actually have some data to work with.
--
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-09 06:49 -0700 |
| Message-ID | <d861f166-2cc0-4879-80c3-68bb2759139d@googlegroups.com> |
| In reply to | #72259 |
On Friday, October 9, 2015 at 4:26:35 PM UTC+4, Richard Heathfield wrote:
> On 09/10/15 10:36, Alla _ wrote:
>
> > Here is the error message I get when I try
> > to compile the program. I don't see why I get
> > this error message.
> >
> > ex8-3.c: In function 'elapsed_time':
> > ex8-3.c:48: error: expected expression before '{' token
> <snip>
>
> > result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
>
> It's complaining about .hour
>
> Is there any particular reason why you can't write
>
> result.hour = time_2.hour - time_1.hour;
> result.minutes = time_2.minutes - time_1.minutes;
> result.seconds = time_2.seconds - time_1.seconds;
>
> ?
>
> It will compile, it's clearer, it requires less typing in a good editor,
> and it makes the bug more obvious and far easier to fix.
>
Thank you! No, of course, there is no obligation for me to use that approach; I was trying different approaches to initialization, which are described in the textbook.
Therefore, I have tried the one you see in the post; also, I have tried
a simpler option with only formulas within curly braces; none has worked.
The main reason I tested those options is because, as I understood it
(maybe erroneously), they provide a concise way to set values to
a structure.
I don't see why the compiler is complaining about hour? Is it
because I don't have a space between first left curly brace and the dot?
> And if you must use scanf (which I regard as an advanced function for
> experts only, and I certainly don't consider myself expert enough to use
> it with confidence), at the very least you should check the return value
> to make sure that you actually have some data to work with.
>
> --
> Richard Heathfield
> Email: rjh at cpax dot org dot uk
> "Usenet is a strange place" - dmr 29 July 1999
> Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-09 16:20 +0100 |
| Message-ID | <mv8lrv$chl$1@dont-email.me> |
| In reply to | #72262 |
On 09/10/2015 14:49, Alla _ wrote: > On Friday, October 9, 2015 at 4:26:35 PM UTC+4, Richard Heathfield wrote: >> It will compile, it's clearer, it requires less typing in a good editor, >> and it makes the bug more obvious and far easier to fix. >> > > Thank you! No, of course, there is no obligation for me to use that approach; I was trying different approaches to initialization, which are described in the textbook. > Therefore, I have tried the one you see in the post; also, I have tried > a simpler option with only formulas within curly braces; none has worked. > > The main reason I tested those options is because, as I understood it > (maybe erroneously), they provide a concise way to set values to > a structure. I think that was the idea. But by the time you add in the dots, parentheses, and the cast within the curly brackets, then it starts to get a bit cluttered. Plus, the style encourages you to put the whole expression on one long line. But also, that's a C99 feature that not everyone will be familiar with. > I don't see why the compiler is complaining about hour? Is it > because I don't have a space between first left curly brace and the dot? It doesn't like .hour because I believe that's only allowed, in this context, within a compound literal. And those need a cast in front. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Alla _ <modelling.data@gmail.com> |
|---|---|
| Date | 2015-10-09 09:27 -0700 |
| Message-ID | <de212fb5-e62e-4bd5-b28d-7b83392e9b7f@googlegroups.com> |
| In reply to | #72266 |
<snip> Thank you!
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-09 19:29 +0100 |
| Message-ID | <87612fki9v.fsf@bsb.me.uk> |
| In reply to | #72266 |
Bartc <bc@freeuk.com> writes:
> On 09/10/2015 14:49, Alla _ wrote:
<snip>
>> I don't see why the compiler is complaining about hour? Is it
>> because I don't have a space between first left curly brace and the dot?
>
> It doesn't like .hour because I believe that's only allowed, in this
> context, within a compound literal. And those need a cast in front.
What's not allowed is the '{'. There is no problem with the .hour (at
least no more that there can be with anything that comes after and
earlier syntax error).
The error message is quit accurate: "expected expression before '{'
token". The parse was looking for a expression of the right hand side
of an assignment. Instead is a token that can start an expression, it
saw a '{' and reported exactly that problem.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-09 14:06 -0700 |
| Message-ID | <ln37xjg3b7.fsf@kst-u.example.com> |
| In reply to | #72266 |
Bartc <bc@freeuk.com> writes:
> On 09/10/2015 14:49, Alla _ wrote:
[...]
>> I don't see why the compiler is complaining about hour? Is it
>> because I don't have a space between first left curly brace and the dot?
>
> It doesn't like .hour because I believe that's only allowed, in this
> context, within a compound literal. And those need a cast in front.
The existing code is (reformatted to avoid long lines):
struct time result;
// ...
result = {.hour = time_2.hour - time_1.hour,
.minutes = time_2.minutes - time_1.minutes,
.seconds = time_2.seconds - time_1.seconds};
The correct version of that code would be:
result = (struct time){.hour = time_2.hour - time_1.hour,
.minutes = time_2.minutes - time_1.minutes,
.seconds = time_2.seconds - time_1.seconds};
The parenthesized type name looks like a cast operator (and
deliberately so, since it does something fairly similar), but
that's not actually what it is. It's part of the syntax of a
compound literal.
You can tell because a cast operator is always followed by an
expression, whereas the `(struct time)` construct here is followed
by something that *isn't* an expression.
Alla, you mentioned that you thought you could omit the type
because it's being assigned to an object of type struct time.
The thing to keep in mind is that, in almost all cases, the type
of an expression is determined by the expression itself, not by
the context in which it appears. In principle a clever compiler
*could* infer the required type for your `{ ... }` based on what it's
assigned to -- but it wouldn't be a C compiler. The parenthesized
type name is not optional.
Also, consider that compound literals were not introduced into the
language until the C99 standard. Not all compilers implement them,
even now in 2015. Whether you use them or not depends in part on
whether you care about compiling your code with pre-C99 compilers.
("No" is a perfectly good answer to that question.)
--
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 | 2015-10-09 22:24 +0100 |
| Message-ID | <mv9b7q$3pk$1@dont-email.me> |
| In reply to | #72332 |
On 09/10/2015 22:06, Keith Thompson wrote:
> struct time result;
> // ...
> result = {.hour = time_2.hour - time_1.hour,
> .minutes = time_2.minutes - time_1.minutes,
> .seconds = time_2.seconds - time_1.seconds};
>
> The correct version of that code would be:
>
> result = (struct time){.hour = time_2.hour - time_1.hour,
> .minutes = time_2.minutes - time_1.minutes,
> Alla, you mentioned that you thought you could omit the type
> because it's being assigned to an object of type struct time.
> The thing to keep in mind is that, in almost all cases, the type
> of an expression is determined by the expression itself, not by
> the context in which it appears. In principle a clever compiler
> *could* infer the required type for your `{ ... }` based on what it's
> assigned to -- but it wouldn't be a C compiler.
Why does it need to be clever? It can do a similar thing to what it does
for ordinary assignments, or exactly what it already does for
initialising using {} and designated initialisers.
It would be interesting to know the rationale behind the need for the
pseudo cast, or examples where it really is needed. Needing it because a
syntax of a={b} is otherwise confusing would be a rather boring reason
though.
True, an assignment is usually followed by an expression, not a left
brace, but neither was it followed by a 'parenthesized type name'. And a
'parenthesized type name' denoting a cast was not usually followed by a
left brace either. So if changes can be made, why not allow "{" to
follow an assignment operator?
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-10-09 15:51 -0700 |
| Message-ID | <lnio6fejvj.fsf@kst-u.example.com> |
| In reply to | #72336 |
Bartc <bc@freeuk.com> writes:
> On 09/10/2015 22:06, Keith Thompson wrote:
>
>> struct time result;
>> // ...
>> result = {.hour = time_2.hour - time_1.hour,
>> .minutes = time_2.minutes - time_1.minutes,
>> .seconds = time_2.seconds - time_1.seconds};
>>
>> The correct version of that code would be:
>>
>> result = (struct time){.hour = time_2.hour - time_1.hour,
>> .minutes = time_2.minutes - time_1.minutes,
>
>> Alla, you mentioned that you thought you could omit the type
>> because it's being assigned to an object of type struct time.
>> The thing to keep in mind is that, in almost all cases, the type
>> of an expression is determined by the expression itself, not by
>> the context in which it appears. In principle a clever compiler
>> *could* infer the required type for your `{ ... }` based on what it's
>> assigned to -- but it wouldn't be a C compiler.
>
> Why does it need to be clever? It can do a similar thing to what it does
> for ordinary assignments, or exactly what it already does for
> initialising using {} and designated initialisers.
For an ordinary assignment, the RHS expression is evaluated in
isolation, without regard to the type of the LHS. The result is then
converted (if necessary and possible) to the RHS type.
For a hypothetical compound literal with no specified type:
{ .hour = 10, minutes = 20, .seconds = 30 }
the compiler in general has no way of knowing its type. (That happens
to be a valid initializer for a `struct time` object; the rules for
initializers are different from those for assignments.) There could
easily be two different incompatible structures with members by those
names.
> It would be interesting to know the rationale behind the need for the
> pseudo cast, or examples where it really is needed. Needing it because a
> syntax of a={b} is otherwise confusing would be a rather boring reason
> though.
>
> True, an assignment is usually followed by an expression, not a left
> brace, but neither was it followed by a 'parenthesized type name'. And a
> 'parenthesized type name' denoting a cast was not usually followed by a
> left brace either. So if changes can be made, why not allow "{" to
> follow an assignment operator?
An assignment is *always* followed by an expression, and a cast operator
is *never* followed by a left brace.
As I said, currently the type of an expression is almost always
determined by the expression itself, not by the context in which it
appears. (Exceptions to this are expressions of array and function
types, which are implicitly converted to pointers in some contexts --
but that's still a conversion, not necessarily a change in the way the
expression itself is evaluated.)
I suppose that when compound literals were introduced in C99, the rules
could have been changed so that the parenthesized type name can be
omitted when the compound literal is the RHS of an assignment, an
argument in a function call where the parameter type is known, or the
expression of a return statement.
That's probably the vast majority of the contexts in which compound
literals are used, and off the top of my head I can't think of any real
drawbacks to such a change (quite possibly I'm missing something).
--
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 | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-09 18:26 +0100 |
| Message-ID | <mv8t7p$aoa$1@dont-email.me> |
| In reply to | #72262 |
On 09/10/15 14:49, Alla _ wrote: <snip> > I don't see why the compiler is complaining about hour? Is it > because I don't have a space between first left curly brace and the dot? The compiler is complaining because it wants you to add a cast. Personally, I don't feel that the cast improves matters. It turns ugly code into uglier code. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2015-10-09 19:24 +0100 |
| Message-ID | <87k2qvkihq.fsf@bsb.me.uk> |
| In reply to | #72282 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 09/10/15 14:49, Alla _ wrote:
>
> <snip>
>
>> I don't see why the compiler is complaining about hour?
No, this is a rare example where Richard is wrong. The compiler is not
complaining about hour (or .hour as Richard originally stated). The
error is: "expected expression before '{' token" and comes from the fact
that the right hand side of the assignment
result = ...
should be an expression, but no C expression starts with a '{'.
>> Is it
>> because I don't have a space between first left curly brace and the dot?
>
> The compiler is complaining because it wants you to add a
> cast. Personally, I don't feel that the cast improves matters. It
> turns ugly code into uglier code.
No, the compiler is asking for a compound literal. It looks like a
cast, but it isn't one. But even if you like to call it one, it
certainly improves matters by making the code code syntactically
correct.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2015-10-09 19:50 +0100 |
| Message-ID | <mv925o$vnh$1@dont-email.me> |
| In reply to | #72293 |
On 09/10/15 19:24, Ben Bacarisse wrote: > Richard Heathfield <rjh@cpax.org.uk> writes: > >> On 09/10/15 14:49, Alla _ wrote: >> >> <snip> >> >>> I don't see why the compiler is complaining about hour? > > No, this is a rare example where Richard is wrong. Touche'! > The compiler is not > complaining about hour (or .hour as Richard originally stated). You're right. It turned out that the one complaining about .hour was not the compiler, but me. >>> Is it >>> because I don't have a space between first left curly brace and the dot? >> >> The compiler is complaining because it wants you to add a >> cast. Personally, I don't feel that the cast improves matters. It >> turns ugly code into uglier code. > > No, the compiler is asking for a compound literal. It looks like a > cast, but it isn't one. Is it not? My apologies. I must confess that I didn't look it up. Without realising it, I was applying the Duck Principle. (If it looks like a duck, swims like a duck, and quacks like a duck...) But okay, does the parenthesised type name that isn't a cast have a correct name? But wait... why am I asking you, when I could look it up for myself? It turns out that the correct term for the parenthesised type name is (after spelling preference normalisation) 'parenthesised type name', which resulted in a wry smile at this end. Perhaps we should find a better name for it. Alas, the only suggestions I could come up with were rather silly, so I will forbear from repeating them here. > But even if you like to call it one, it > certainly improves matters by making the code code syntactically > correct. I know you'll disagree, and I know I'm curmudging, but in this case I think that that particular way of making the code syntactically correct actually makes matters worse, because I think it makes the code less readable and I think Alla will consequently discover that her bug is harder to find and harder to fix. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-10-09 15:56 -0400 |
| Message-ID | <mv961o$dr6$2@dont-email.me> |
| In reply to | #72297 |
On 10/9/2015 2:50 PM, Richard Heathfield wrote:
> On 09/10/15 19:24, Ben Bacarisse wrote:
>>[...]
>> No, the compiler is asking for a compound literal. It looks like a
>> cast, but it isn't one.
>
> Is it not? My apologies. I must confess that I didn't look it up.
> Without realising it, I was applying the Duck Principle. (If it looks
> like a duck, swims like a duck, and quacks like a duck...) But okay,
> does the parenthesised type name that isn't a cast have a correct name?
>
> But wait... why am I asking you, when I could look it up for myself?
>
> It turns out that the correct term for the parenthesised type name is
> (after spelling preference normalisation) 'parenthesised type name',
> which resulted in a wry smile at this end.
>
> Perhaps we should find a better name for it. Alas, the only suggestions
> I could come up with were rather silly, so I will forbear from repeating
> them here.
I propose "splint."
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-10-09 15:31 -0400 |
| Message-ID | <mv94i6$a2q$1@dont-email.me> |
| In reply to | #72262 |
On 10/09/2015 09:49 AM, Alla _ wrote:
> On Friday, October 9, 2015 at 4:26:35 PM UTC+4, Richard Heathfield wrote:
>> On 09/10/15 10:36, Alla _ wrote:
>>
>>> Here is the error message I get when I try
>>> to compile the program. I don't see why I get
>>> this error message.
>>>
>>> ex8-3.c: In function 'elapsed_time':
>>> ex8-3.c:48: error: expected expression before '{' token
>> <snip>
>>
>>> result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
>>
>> It's complaining about .hour
>>
>> Is there any particular reason why you can't write
>>
>> result.hour = time_2.hour - time_1.hour;
>> result.minutes = time_2.minutes - time_1.minutes;
>> result.seconds = time_2.seconds - time_1.seconds;
>>
>> ?
>>
>> It will compile, it's clearer, it requires less typing in a good editor,
>> and it makes the bug more obvious and far easier to fix.
>>
>
> Thank you! No, of course, there is no obligation for me to use that approach; I was trying different approaches to initialization, which are described in the textbook.
The fundamental problem is that you're not doing initialization.
Designated initializer are only recognized during initialization. This
would work fine:
struct time result = {.hour = time_2.hour - time_1.hour,
.minutes = time_2.minutes - time_1.minutes,
.seconds = time_2.seconds - time_1.seconds};
In your code, you were trying to assign a new value to 'result';
assignment follows different rules than initialization. This, however,
would have worked, for a very different reason:
result = (struct time) {.hour = time_2.hour - time_1.hour,
.minutes = time_2.minutes - time_1.minutes,
.seconds = time_2.seconds - time_1.seconds};
The right operand of that assignment statement is a compound literal. It
creates an unnamed temporary object of type "struct type", and
initializes it - so initialization syntax is allowed. Then the value of
that temporary is copied to result. This code is essentially equivalent to:
struct time result;
{
struct time __unnamed_temporary = {
.hour = time_2.hour - time_1.hour,
.minutes = time_2.minutes - time_1.minutes,
.seconds = time_2.seconds - time_1.seconds};
result = __unnamed_temporary;
}
> Therefore, I have tried the one you see in the post; also, I have tried
> a simpler option with only formulas within curly braces; none has worked.
>
> The main reason I tested those options is because, as I understood it
> (maybe erroneously), they provide a concise way to set values to
> a structure.
Not really - in any context where it's legal to use designated
initializers to initialize all or most of the members of a struct, it's
more concise to not use them:
struct time result = {time_2.hour - time_1.hour,
time_2.minutes - time_1.minutes, time_2.seconds - time_1.seconds};
That sets the first three members of result to the specified values,
regardless of what names those three members have. The danger of this
approach is that you need to make sure that the first three members of
struct time are indeed hour, minute, and second.
What designated initializers provide is a convenient way to initialize
just a few specified elements of a struct object, while setting all of
the others zero-initialized.
> I don't see why the compiler is complaining about hour? Is it
> because I don't have a space between first left curly brace and the dot?
Because .hour doesn't mean anything in that context. It only means
something in the context of an initialization, and that wasn't an
initialization.
--
James Kuyper
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-10-10 06:57 -0700 |
| Message-ID | <kfn8u7a25d7.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #72262 |
Alla _ <modelling.data@gmail.com> writes:
> On Friday, October 9, 2015 at 4:26:35 PM UTC+4, Richard Heathfield wrote:
>> On 09/10/15 10:36, Alla _ wrote:
>>
>>> Here is the error message I get when I try
>>> to compile the program. I don't see why I get
>>> this error message.
>>>
>>> ex8-3.c: In function 'elapsed_time':
>>> ex8-3.c:48: error: expected expression before '{' token
>>
>> <snip>
>>
>>> result = {.hour = time_2.hour - time_1.hour, .minutes = time_2.minutes - time_1.minutes, .seconds = time_2.seconds - time_1.seconds};
>>
>> It's complaining about .hour
>>
>> Is there any particular reason why you can't write
>>
>> result.hour = time_2.hour - time_1.hour;
>> result.minutes = time_2.minutes - time_1.minutes;
>> result.seconds = time_2.seconds - time_1.seconds;
>>
>> ?
>>
>> It will compile, it's clearer, it requires less typing in a good editor,
>> and it makes the bug more obvious and far easier to fix.
>
> Thank you! No, of course, there is no obligation for me to use
> that approach; I was trying different approaches to
> initialization, which are described in the textbook.
>
> Therefore, I have tried the one you see in the post; also, I have
> tried a simpler option with only formulas within curly braces;
> none has worked.
>
> The main reason I tested those options is because, as I understood
> it (maybe erroneously), they provide a concise way to set values
> to a structure.
Here is another perspective for your consideration. My advice is
to disregard the advice of people who say not to use compound
literals. The main value of using compound literals is not
whether the code is shorter or longer (though in most cases it
will be shorter), but that it expresses what is needed directly
rather than indirectly. With that in mind, here is an alternate
writing for part of the program you are working on. The idea is
to convert the parts of a 'struct time' value into units of
seconds, subtract the seconds, and then convert the difference
back into a 'struct time' value. The different parts decompose
easily into three functions. Note the last function, which makes
use of a compound literal.
typedef long long Seconds;
Seconds seconds_in( struct time );
struct time seconds_to_time( Seconds );
// Function to compute elapsed time
struct time
elapsed_time( struct time t1, struct time t2 ){
return seconds_to_time( seconds_in( t2 ) - seconds_in( t1 ) );
}
Seconds
seconds_in( struct time t ){
return (t.hour * 60LL + t.minutes) * 60 + t.seconds;
}
struct time
seconds_to_time( Seconds seconds ){
return (struct time){
.hour = seconds / 60 / 60,
.minutes = seconds / 60 % 60,
.seconds = seconds % 60
};
}
I think you should be able to follow this code fairly easily.
The first two functions are not too complicated, hopefully they
present no problems for you. The last function composes a
'struct time' value by means of a compound literal. Since all
that is done with that structure value is to return it, this
function also can have just a single statement, which is a
'return' of the structure value. Each structure member has a
corresponding expression that produces the value needed for that
member. That expresses what the function needs to do pretty
directly, rather than computing a value in multiple steps.
Do you see what I'm trying to say?
The comments after this point are secondary (and optional),
please read them only after understanding the previous comments.
There is potentially a problem in the last function, which is
what happens if 'seconds' is negative. There is an easy way
of dealing with this, although it may look complicated when
you first see it. The idea is to arrange to always deal with
positive (or zero) values, and then adjust the negativeness
appropriately after computing each component value. Here is
the code:
struct time
seconds_to_time( Seconds seconds ){
signed sign = seconds < 0 ? -1 : 1;
return (struct time){
.hour = seconds * sign / 60 / 60 * sign,
.minutes = seconds * sign / 60 % 60 * sign,
.seconds = seconds * sign % 60 * sign
};
}
If 'seconds' is greater than or equal to zero, then 'sign' is 1,
and the values are the same as if the '* sign' pieces were all
left out. If seconds is less than zero, then 'sign' is -1, so
'seconds * sign' is a positive number, which is then used to do
the computation in each case, with the final '* sign' turning
postive values into their corresponding negatives. Are you
able to follow all this? It may look a bit daunting but I think
it's not too bad if you work through the different cases.
[toc] | [prev] | [next] | [standalone]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-10-10 17:25 +0100 |
| Message-ID | <mvbe1p$3fb$1@dont-email.me> |
| In reply to | #72394 |
On 10/10/2015 14:57, Tim Rentsch wrote:
> Here is another perspective for your consideration. My advice is
> to disregard the advice of people who say not to use compound
> literals. The main value of using compound literals is not
> whether the code is shorter or longer (though in most cases it
> will be shorter), but that it expresses what is needed directly
> rather than indirectly.
The problem is that, as they are implemented in C, they tend to have
rather more clutter than is desired, which reduces the expressiveness.
> struct time
> seconds_to_time( Seconds seconds ){
> return (struct time){
> .hour = seconds / 60 / 60,
> .minutes = seconds / 60 % 60,
> .seconds = seconds % 60
> };
> }
What would that last function look like without compound literals? Perhaps:
struct time seconds_to_tims(Seconds seconds) {
struct time T = {seconds/60/60, seconds/60%60, seconds%60};
return T;
}
Not too bad. Or even like this (less dependent on how struct time is
defined and with fewer divide and mod operations):
struct time seconds_to_tims(Seconds seconds) {
struct time T;
T.hours = seconds/3600;
T.minutes = (seconds-T.hours*3600)/60;
T.seconds = seconds-T.hours*3600-T.minutes*60
return T;
}
> struct time
> seconds_to_time( Seconds seconds ){
> signed sign = seconds < 0 ? -1 : 1;
> return (struct time){
> .hour = seconds * sign / 60 / 60 * sign,
> .minutes = seconds * sign / 60 % 60 * sign,
> .seconds = seconds * sign % 60 * sign
> };
> }
Perhaps an easier way is to take your original function and add this
line at the start:
if (seconds<0) return seconds_to_time(-seconds);
--
Bartc
[toc] | [prev] | [next] | [standalone]
Page 1 of 3 [1] 2 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web