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


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

Program to compute elapsed time, learning structures and functions

Started byAlla _ <modelling.data@gmail.com>
First post2015-10-09 02:36 -0700
Last post2015-11-05 15:50 -0800
Articles 20 on this page of 49 — 12 participants

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


Contents

  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 →


#72251 — Program to compute elapsed time, learning structures and functions

FromAlla _ <modelling.data@gmail.com>
Date2015-10-09 02:36 -0700
SubjectProgram 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]


#72253

FromBartc <bc@freeuk.com>
Date2015-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]


#72255

FromAlla _ <modelling.data@gmail.com>
Date2015-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]


#72254

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#72256

FromAlla _ <modelling.data@gmail.com>
Date2015-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]


#72259

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-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]


#72262

FromAlla _ <modelling.data@gmail.com>
Date2015-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]


#72266

FromBartc <bc@freeuk.com>
Date2015-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]


#72275

FromAlla _ <modelling.data@gmail.com>
Date2015-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]


#72294

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#72332

FromKeith Thompson <kst-u@mib.org>
Date2015-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]


#72336

FromBartc <bc@freeuk.com>
Date2015-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]


#72346

FromKeith Thompson <kst-u@mib.org>
Date2015-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]


#72282

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-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]


#72293

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-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]


#72297

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-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]


#72313

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-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]


#72305

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-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]


#72394

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-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]


#72396

FromBartc <bc@freeuk.com>
Date2015-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