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


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

Negative effects of c++ in C

Started byjacobnavia <jacob@jacob.remcomp.fr>
First post2016-11-22 11:18 +0100
Last post2016-11-24 14:55 +0100
Articles 6 on this page of 26 — 10 participants

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


Contents

  Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 11:18 +0100
    Re: Negative effects of c++ in C Noob <root@127.0.0.1> - 2016-11-22 11:46 +0100
      Re: Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 14:48 +0100
        Re: Big main() "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-22 21:51 +0800
        Re: Negative effects of c++ in C Noob <root@127.0.0.1> - 2016-11-22 15:29 +0100
        Re: Negative effects of c++ in C antispam@math.uni.wroc.pl - 2016-11-22 15:09 +0000
      Re: Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 16:58 +0100
    Re: Negative effects of c++ in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-22 14:29 +0000
      Re: Negative effects of c++ in C David Brown <david.brown@hesbynett.no> - 2016-11-22 15:58 +0100
        Re: Negative effects of c++ in C Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-11-22 15:55 +0000
        Re: Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 17:01 +0100
          Re: Negative effects of c++ in C Noob <root@127.0.0.1> - 2016-11-22 18:32 +0100
          Re: Negative effects of c++ in C David Brown <david.brown@hesbynett.no> - 2016-11-23 00:19 +0100
    [OT] It's only words... :) "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-22 22:55 +0800
      Re: [OT] It's only words... :) "Mr. Man-wai Chang" <toylet.toylet@gmail.com> - 2016-11-22 22:57 +0800
    Re: Negative effects of c++ in C Ian Collins <ian-news@hotmail.com> - 2016-11-23 08:43 +1300
      Re: Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 21:14 +0100
      Re: Negative effects of c++ in C jacobnavia <jacob@jacob.remcomp.fr> - 2016-11-22 21:17 +0100
    Re: Negative effects of c++ in C rockbrentwood@gmail.com - 2016-11-23 15:41 -0800
      Re: Negative effects of c++ in C supercat@casperkitty.com - 2016-11-23 16:19 -0800
        Re: Negative effects of c++ in C David Brown <david.brown@hesbynett.no> - 2016-11-24 14:06 +0100
          Re: Negative effects of c++ in C supercat@casperkitty.com - 2016-11-24 07:36 -0800
            Re: Negative effects of c++ in C David Brown <david.brown@hesbynett.no> - 2016-11-25 00:23 +0100
              Re: Negative effects of c++ in C supercat@casperkitty.com - 2016-11-25 09:42 -0800
      Re: Negative effects of c++ in C Keith Thompson <kst-u@mib.org> - 2016-11-23 16:34 -0800
        Re: Negative effects of c++ in C David Brown <david.brown@hesbynett.no> - 2016-11-24 14:55 +0100

Page 2 of 2 — ← Prev page 1 [2]


#97384

FromDavid Brown <david.brown@hesbynett.no>
Date2016-11-24 14:06 +0100
Message-ID<o16ohq$r1o$1@dont-email.me>
In reply to#97373
On 24/11/16 01:19, supercat@casperkitty.com wrote:
> On Wednesday, November 23, 2016 at 5:41:57 PM UTC-6, rockbr...@gmail.com wrote:
>> But here's one issue that's really hit the sore spot for me. The "auto" keyword is woefully underused and ISO wants to waste a perfectly good legacy by trashing it ... only to replace its natural generalization with one of its 201x "keywords" (which look like warts on the language).
> 
> How about the "register" keyword?  Making the use of "register" on a variable
> which is exposed to outside code or has its address taken is a constraint
> violation, but if that weren't the case the keyword could serve as a useful
> annotation that an lvalue will not have its value accessed using a pointer
> *except* within the context of a sub-expression where its address is taken;
> within such a context, one of two conditions must apply:
> 
>    1. All accesses to the lvalue must be performed using the result of the
>       address-of operator or a pointer derived therefrom.
> 
>    2. All accesses to the lvalue by any means must be reads.
> 
> Allowing the "register" qualifier to be used in such fashion would give the
> compiler useful information it would not otherwise have; given something
> like:
> 
>     int foo(void)
>     {
>       register int x = 0;
>       if (getvalue(&x))
>       {
>         x++;
>         foo();
>         x++;
>         bar();
>       }
>       return x;
>     }
> 
> present rules would require a compiler to pessimistically allow for the
> possibility that "foo" and/or "bar" might access x unless it could see
> into the code for them and/or "getvalue".  Defining the "register" keyword
> as indicated would tell the compiler those functions won't access "x",
> allowing it to be safely kept in a register across calls to them.
> 

It is true that this could give a small extra optimisation opportunity.
 But it would be a very, very small improvement, with few use-cases and
negligible effect in those cases (function call overhead would swamp the
extra load and store needed for x here).  And there is already a clear
and simple way to get the same effect - just make a new local variable:

int foo(void) {
  int x = 0;
  if (getvalue(&x)) {
    int y = x;
    y++;
    foo();
    y++;
    bar();
    return y;
  }
  return x;
}

"register" as a keyword is practically non-existent in C from the last
20 years, just like "auto".  Except for compiler extensions such as
gcc's "register asm" construction, there is no point in using it -
modern compilers ignore it other than for checking constraint violations.

As long as compilers continue to provide support for specific C standard
versions (such as gcc's "-std" flag), I can't see any harm in dropping
the current use of "register" or "auto", and letting the keywords be
recycled for better use.  C++ has done so for "auto", and is doing so
for "register".

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


#97401

Fromsupercat@casperkitty.com
Date2016-11-24 07:36 -0800
Message-ID<7dfa5c08-4bf0-44a8-97a0-8fffda799c4e@googlegroups.com>
In reply to#97384
On Thursday, November 24, 2016 at 7:06:28 AM UTC-6, David Brown wrote:
> On 24/11/16 01:19, supercat wrote:
> > How about the "register" keyword?  Making the use of "register" on a variable
> > which is exposed to outside code or has its address taken is a constraint
> > violation, but if that weren't the case the keyword could serve as a useful
> > annotation that an lvalue will not have its value accessed using a pointer
> > *except* within the context of a sub-expression where its address is taken;

> It is true that this could give a small extra optimisation opportunity.
>  But it would be a very, very small improvement, with few use-cases and
> negligible effect in those cases (function call overhead would swamp the
> extra load and store needed for x here).  And there is already a clear
> and simple way to get the same effect - just make a new local variable:

One can often work around the lack of a qualifier by copying things to
temporary variables, but sometimes that would be a performance gain (a big
one, if it lets compilers consolidate operations on a variable) and
sometimes a performance loss (if it causes register spillage).  A compiler
will generally know better than a programmer whether use of a temporary
would be profitable.

Still, a better example might have been to illustrate global variables:


    extern register uint8_t *buff_stuff,*buff_start,*buff_end;
    void store_byte(uint8_t dat)
    {
      if (buff_stuff >= buff_end)
        buff_stuff = buff_start;
      *buff_stuff++ = dat;
    }

If code calls buff_stuff within a loop, a compiler may be able to hoist
the comparison and then treat the code as one or two memcpy/memset
operations.  Without the register qualifier, a compiler would have to
reload pointers on each pass through the loop.

> "register" as a keyword is practically non-existent in C from the last
> 20 years, just like "auto".  Except for compiler extensions such as
> gcc's "register asm" construction, there is no point in using it -
> modern compilers ignore it other than for checking constraint violations.

Is any purpose served by making the indicated usage constraint violations?
Allowing compilers to reject programas that take the address of a register-
qualified variable would help single-pass compilers, but requiring them to
reject such programs forces them to do extra work.

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


#97432

FromDavid Brown <david.brown@hesbynett.no>
Date2016-11-25 00:23 +0100
Message-ID<o17smv$5fb$1@dont-email.me>
In reply to#97401
On 24/11/16 16:36, supercat@casperkitty.com wrote:
> On Thursday, November 24, 2016 at 7:06:28 AM UTC-6, David Brown wrote:
>> On 24/11/16 01:19, supercat wrote:
>>> How about the "register" keyword?  Making the use of "register" on a variable
>>> which is exposed to outside code or has its address taken is a constraint
>>> violation, but if that weren't the case the keyword could serve as a useful
>>> annotation that an lvalue will not have its value accessed using a pointer
>>> *except* within the context of a sub-expression where its address is taken;
>
>> It is true that this could give a small extra optimisation opportunity.
>>   But it would be a very, very small improvement, with few use-cases and
>> negligible effect in those cases (function call overhead would swamp the
>> extra load and store needed for x here).  And there is already a clear
>> and simple way to get the same effect - just make a new local variable:
>
> One can often work around the lack of a qualifier by copying things to
> temporary variables, but sometimes that would be a performance gain (a big
> one, if it lets compilers consolidate operations on a variable) and
> sometimes a performance loss (if it causes register spillage).  A compiler
> will generally know better than a programmer whether use of a temporary
> would be profitable.
>

Compilers don't use the "register" keyword as a command to put data in a 
register.  They don't even use it as a hint these days, nor have they 
done for a great many years.  The compiler chooses the best (as far as 
it can tell) options for data in registers, and when to consolidate 
operations on variables.  The "register" keyword plays no part in that.

> Still, a better example might have been to illustrate global variables:
>
>
>      extern register uint8_t *buff_stuff,*buff_start,*buff_end;
>      void store_byte(uint8_t dat)
>      {
>        if (buff_stuff >= buff_end)
>          buff_stuff = buff_start;
>        *buff_stuff++ = dat;
>      }

I don't believe it is legal to have an "extern register" declaration.

>
> If code calls buff_stuff within a loop, a compiler may be able to hoist
> the comparison and then treat the code as one or two memcpy/memset
> operations.  Without the register qualifier, a compiler would have to
> reload pointers on each pass through the loop.

Even if it were legal, you get the same effect by simply using local 
variables rather than manipulating the stored values directly.

>
>> "register" as a keyword is practically non-existent in C from the last
>> 20 years, just like "auto".  Except for compiler extensions such as
>> gcc's "register asm" construction, there is no point in using it -
>> modern compilers ignore it other than for checking constraint violations.
>
> Is any purpose served by making the indicated usage constraint violations?
> Allowing compilers to reject programas that take the address of a register-
> qualified variable would help single-pass compilers, but requiring them to
> reject such programs forces them to do extra work.
>

There are no single-pass compilers of significance.  Compiler effort is 
irrelevant in almost every circumstance - programmer effort, and 
run-time cpu effort matters, but (within reason) compiler time and 
effort is not an issue to worry about.

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


#97467

Fromsupercat@casperkitty.com
Date2016-11-25 09:42 -0800
Message-ID<89d7ced0-5100-4197-96fd-c34d4f0ef5b3@googlegroups.com>
In reply to#97432
On Thursday, November 24, 2016 at 5:23:28 PM UTC-6, David Brown wrote:
> On 24/11/16 16:36, supercat wrote:
> > One can often work around the lack of a qualifier by copying things to
> > temporary variables, but sometimes that would be a performance gain (a big
> > one, if it lets compilers consolidate operations on a variable) and
> > sometimes a performance loss (if it causes register spillage).  A compiler
> > will generally know better than a programmer whether use of a temporary
> > would be profitable.
> 
> Compilers don't use the "register" keyword as a command to put data in a 
> register.  They don't even use it as a hint these days, nor have they 
> done for a great many years.  The compiler chooses the best (as far as 
> it can tell) options for data in registers, and when to consolidate 
> operations on variables.  The "register" keyword plays no part in that.

It presently plays no part, because all of the cases where it would be
useful are presently regarded as constraint violations by the Standard.

All that would be necessary for compilers to support my proposed usage
would be to ignore the qualifier in a number of cases where it would be a
constraint violation.  The simplest way to accomplish that would be for
the Standard to allow compilers to ignore the keyword altogether, but
specify that compilers are allowed to reject code which uses it in ways
that would still be inappropriate (e.g. "for (;;register)").  As it is,
the register keyword has costs but zero benefit.  Eliminating it as a
constraint violation would reduce the cost considerably [an implementation
could simply pre-define a macro called "register" which expands to
nothing], while allowing for possible benefits on those compilers that
chose to exploit the new semantics.

> > Still, a better example might have been to illustrate global variables:
> >
> >
> >      extern register uint8_t *buff_stuff,*buff_start,*buff_end;
> >      void store_byte(uint8_t dat)
> >      {
> >        if (buff_stuff >= buff_end)
> >          buff_stuff = buff_start;
> >        *buff_stuff++ = dat;
> >      }
> 
> I don't believe it is legal to have an "extern register" declaration.

It is presently a constraint violation.  Because of that, allowing such
declarations with new semantics would not break any conforming code.

> > If code calls buff_stuff within a loop, a compiler may be able to hoist
> > the comparison and then treat the code as one or two memcpy/memset
> > operations.  Without the register qualifier, a compiler would have to
> > reload pointers on each pass through the loop.
> 
> Even if it were legal, you get the same effect by simply using local 
> variables rather than manipulating the stored values directly.

Where would such a variable be declared?  The variables can't be local
to store_byte, and the calling code shouldn't need to know anything about
them.

> > Is any purpose served by making the indicated usage constraint violations?
> > Allowing compilers to reject programas that take the address of a register-
> > qualified variable would help single-pass compilers, but requiring them to
> > reject such programs forces them to do extra work.
> 
> There are no single-pass compilers of significance.  Compiler effort is 
> irrelevant in almost every circumstance - programmer effort, and 
> run-time cpu effort matters, but (within reason) compiler time and 
> effort is not an issue to worry about.

I wouldn't be opposed to making tolerance for presently-disallowed uses
of the keyword mandatory, but would want to avoid opposition from anyone
who claims the new meanings of the keyword might require compilers to do
some extra work.  Even on a single-pass compiler, it would not be hard
to have the act of taking a variable's address allocate a new non-register
variable and store the value to that, setting a compiler flag to ensure
that the register gets reloaded before code branches back to anyplace
which had expected the variable to be in a register.

If one looks at the situations where "restrict" would be insufficient to
tell the compiler everything it would need to know about aliasing, a lot
of them involve the patterns which would be covered by the indicated use
of the "register" keyword.

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


#97375

FromKeith Thompson <kst-u@mib.org>
Date2016-11-23 16:34 -0800
Message-ID<ln1sy1d8c3.fsf@kst-u.example.com>
In reply to#97370
rockbrentwood@gmail.com writes:
[...]
> But here's one issue that's really hit the sore spot for me. The
> "auto" keyword is woefully underused and ISO wants to waste a
> perfectly good legacy by trashing it ... only to replace its natural
> generalization with one of its 201x "keywords" (which look like warts
> on the language).

The "auto" keyword is essentially useless in C, but C++ (starting in
C++11, I think) has re-used the "auto" keyword for its own purposes.  I
wouldn't mind if C followed suit, but there aren't as many advantages
for C as for C++.

In C++, this:
    auto var = expr;
causes var to have the type of expr.

> Take a close look at the places _thread_local is used. Inside a block
> it may only occur with static or extern, while auto may never occur
> with either. Outside it may freely be used, while auto may never be
> used.
>
> The literal meaning of auto is to denote a variable that's heaped on
> the call frame for a subroutine. But the ESSENTIAL meaning is to
> denote a variable that's heaped on a separately called program thread
> -- regardless of whether it's called as a subroutine or spawned as a
> separate thread.

Subroutines/functions are not threads.  A called function executes in
the same thread as its caller.

> In a unified framework that embodies both cases, a subroutine itself
> may be regarded as equivalent to a thread that suspends its caller and
> then resumes the caller when it returns.

What you call "a thread that suspends it caller", I call "not a thread".

> So, instead of phasing out the "auto" keyword only to replace it in
> these other contexts by another (wart of a) keyword, just simply use
> auto for all the contexts and do away with "thread_local" entirely.

_Thread_local (not _thread_local) is already in the language.  The word
"auto" does not, to me, suggest the same thing that _Thread_local does.

-- 
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]


#97390

FromDavid Brown <david.brown@hesbynett.no>
Date2016-11-24 14:55 +0100
Message-ID<o16ren$6ef$1@dont-email.me>
In reply to#97375
On 24/11/16 01:34, Keith Thompson wrote:
> rockbrentwood@gmail.com writes:
> [...]
>> But here's one issue that's really hit the sore spot for me. The
>> "auto" keyword is woefully underused and ISO wants to waste a
>> perfectly good legacy by trashing it ... only to replace its natural
>> generalization with one of its 201x "keywords" (which look like warts
>> on the language).
> 
> The "auto" keyword is essentially useless in C, but C++ (starting in
> C++11, I think) has re-used the "auto" keyword for its own purposes.  I
> wouldn't mind if C followed suit, but there aren't as many advantages
> for C as for C++.
> 

gcc has the "__auto_type" for C that works mostly like "auto" in C++11.
 There are a few restrictions, such as only supporting a single variable
definition at a time (which is good practice anyway), but basically it
does the same job.

The primary motivation for it was to implement <stdatomic> type-generic
atomic macros in gcc.  These are, of course, part of the implementation,
so the compiler is free to use implementation-specific extensions to
make the macros.

But for those that are happy to use gcc extensions, __auto_type is
available in C.  And you can use "#define auto __auto_type", though I
think that is undefined behaviour according to the standards (but seems
to work fine in gcc, as long as you don't need the normal use of "auto"
in your code).

> In C++, this:
>     auto var = expr;
> causes var to have the type of expr.
> 
>> Take a close look at the places _thread_local is used. Inside a block
>> it may only occur with static or extern, while auto may never occur
>> with either. Outside it may freely be used, while auto may never be
>> used.
>>
>> The literal meaning of auto is to denote a variable that's heaped on
>> the call frame for a subroutine. But the ESSENTIAL meaning is to
>> denote a variable that's heaped on a separately called program thread
>> -- regardless of whether it's called as a subroutine or spawned as a
>> separate thread.
> 
> Subroutines/functions are not threads.  A called function executes in
> the same thread as its caller.
> 
>> In a unified framework that embodies both cases, a subroutine itself
>> may be regarded as equivalent to a thread that suspends its caller and
>> then resumes the caller when it returns.
> 
> What you call "a thread that suspends it caller", I call "not a thread".
> 
>> So, instead of phasing out the "auto" keyword only to replace it in
>> these other contexts by another (wart of a) keyword, just simply use
>> auto for all the contexts and do away with "thread_local" entirely.
> 
> _Thread_local (not _thread_local) is already in the language.  The word
> "auto" does not, to me, suggest the same thing that _Thread_local does.
> 

Agreed.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

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


csiph-web