Friday, January 13, 2017

Digest for comp.lang.c++@googlegroups.com - 25 updates in 9 topics

"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Jan 12 08:29PM -0800

On Thursday, January 12, 2017 at 4:13:58 PM UTC-5, Richard wrote:
 
> Yes, you are using an IDE for typing. They do much more than that.
 
> Oh, and gdb is absolutely horrible. It hasn't changed in 20+ years
> since I first used it. The VS debugger crushes gdb.
 
I agree. Microsoft's Visual Studio development platform is second
to none. It is the model I am seeking to use as a base for my own
IDE. I have the same drag/drop/popout window plan, along with some
new extensions I'd like to see.
 
Best regards,
Rick C. Hodgin
scott@slp53.sl.home (Scott Lurndal): Jan 13 01:25PM


>Yes, you are using an IDE for typing. They do much more than that.
 
>Oh, and gdb is absolutely horrible. It hasn't changed in 20+ years
>since I first used it. The VS debugger crushes gdb.
 
VS doesn't run on linux. That automatically makes it a non-starter.
legalize+jeeves@mail.xmission.com (Richard): Jan 12 09:13PM

[Please do not mail me a copy of your followup]
 
Ian Collins <ian-news@hotmail.com> spake the secret code
 
>On 01/13/17 07:29 AM, Scott Lurndal wrote:
>> There are a dozen native IDE's available for linux with all the
>> same features as VS.
 
Clearly you don't use VS for anything more fancy than typing.
 
There is only one IDE that comes even close to VS productivity and
that is CLion.
 
>> But none of them are as useful than VIM+Make+GDB.
 
Yes, you are using an IDE for typing. They do much more than that.
 
Oh, and gdb is absolutely horrible. It hasn't changed in 20+ years
since I first used it. The VS debugger crushes gdb.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Cholo Lennon <chololennon@hotmail.com>: Jan 13 11:06AM -0300

On 01/12/2017 06:13 PM, Richard wrote:
 
> Clearly you don't use VS for anything more fancy than typing.
 
> There is only one IDE that comes even close to VS productivity and
> that is CLion.
 
I haven't tested CLion very well (is not free), but I use other IDEs
from Jetbrains (IntelliJ/PyCharm), they are really good. On
Linux/Solaris I use Eclipse CDT for C++, it's not bad and in some
categories is (way) better than VS.
 
 
 
> Yes, you are using an IDE for typing. They do much more than that.
 
> Oh, and gdb is absolutely horrible. It hasn't changed in 20+ years
> since I first used it. The VS debugger crushes gdb.
 
I agree
 
 
--
Cholo Lennon
Bs.As.
ARG
JiiPee <no@notvalid.com>: Jan 12 11:30PM

On 12/01/2017 23:23, Stefan Ram wrote:
>> it did not deal with it when I used an object (instead of and
>> index)
> How can you know whether this really runs slower?
 
 
I debugged the code line by line (in release mode). And it did create a
temporary s in inline function.
JiiPee <no@notvalid.com>: Jan 12 11:15PM

On 12/01/2017 22:30, Stefan Ram wrote:
 
> SCOTT MEYERS
 
> "Guideline: Con.4: Use const to define objects with
> values that do not change after construction"
 
sure
JiiPee <no@notvalid.com>: Jan 12 11:15PM

On 12/01/2017 21:52, Stefan Ram wrote:
>> , where array is arr's array. But it has this extra temporary variable
>> int index{1}; . So how can I get rid of that temporary?
> Don't worry. The optimizer can deal with such minutiae.
 
Are you 100% sure? it did not deal with it when I used an object
(instead of and index)
ram@zedat.fu-berlin.de (Stefan Ram): Jan 12 11:38PM

>I debugged the code line by line (in release mode). And it did create a
>temporary s in inline function.
 
Lines of assembler, I suppose.
 
I was just writing about this in comp.lang.iso-c++.
 
Here's a program:
 
#include <cstdlib>
 
static void escape( void * p )
{ asm volatile( "" : : "g"(p) : "memory" ); }
 
struct object
{ constexpr explicit object( int const n ): value{ n } {}
object & operator +=( object const other )
{ this->value += other.value; return *this; }
int value; };
 
static object operator +( object n, const object m )
{ n += m; return n; }
 
int main()
{ constexpr object a{ 0x1001 }, b{ 0x1002 }, c{ 0x1003 };
auto const r = a +( b + c );
escape( &( r.value )); }
 
It is effectively being compile into:
 
MOVL #$3006, 32( %rsp )
 
. I used »-Ofast -O3 -fgcse -fgcse-las« (I don't know
whether these options are needed for this effect).
 
But for debugging, I'd rather use something more like »-Og
-g«. This might already have an effect on the compilation.
Not to speak of the effect of adding debug statements.
ram@zedat.fu-berlin.de (Stefan Ram): Jan 12 09:52PM

>, where array is arr's array. But it has this extra temporary variable
>int index{1}; . So how can I get rid of that temporary?
 
Don't worry. The optimizer can deal with such minutiae.
 
I'd write this as
 
int & get( int const index ) const { return array[ i ]; }
 
(untested).
 
Guidelines:
 
SL.10: Prefer using STL array or vector instead of a C array
 
Bounds.2: Only index into arrays using constant expressions.
ram@zedat.fu-berlin.de (Stefan Ram): Jan 12 10:21PM

>Con.4: Use const to define objects with values that do not
>change after construction
 
If you prefer Scott Meyers:
 
»Use const whenever possible.« -- SCOTT MEYERS
Paul <pepstein5@gmail.com>: Jan 13 03:55AM -0800

The text at the end of this message is from stackoverflow,
and it seems to say that C c = C();
value initializes c without calling the default constructor. I thought
that C() did call the default constructor. For example, I just tried to
compile the code:
struct C
{
C(int ){}
int x;
};
int main()
{
C c = C();
}
 
I got a compiler error saying that C::C() has no matching function. This
compiler message is exactly what I expected. But it seems that
the passage below says that C c = C(); is fine and has the effect
of value-initializing c.x Is the below passage just wrong?
Please note that I'm happy with the way my compiler behaved. My problem
is with the below passage. Many thanks for your help.

Paul
 
BEGIN QUOTE
Implicitly defined (by the compiler) default constructor of a class does not initialize members of built-in types.
 
However, you have to keep in mind that in some cases the initialization of a instance of the class can be performed by other means. Not by default constructor, nor by constructor at all.
 
For example, there's a widespread incorrect belief that for class C the syntax C() always invokes default constructor. In reality though, the syntax C() performs so called value-initialization of the class instance. It will only invoke the default constructor if it is user-declared. (That's in C++03. In C++98 - only if the class is non-POD). If the class has no user-declared constructor, then the C() will not call the compiler-provided default constructor, but rather will perform a special kind of initialization that does not involve the constructor of C at all. Instead, it will directly value-initialize every member of the class. For built-in types it results in zero-initialization.
END QUOTE
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 13 02:20PM +0100

On 13.01.2017 12:55, Paul wrote:
> The text at the end of this message is from stackoverflow,
> and it seems to say that C c = C();
> value initializes c
 
Yes.
 
 
> without calling the default constructor.
 
In the case where there is no default constructor.
 
 
> I thought that C() did call the default constructor.
 
It can't do that when there isn't one.
 
 
> }
 
> I got a compiler error saying that C::C() has no matching function. This
> compiler message is exactly what I expected.
 
Right.
 
 
Cheers & hth.,
 
- Alf
David Brown <david.brown@hesbynett.no>: Jan 13 12:06PM +0100

On 12/01/17 17:44, JiiPee wrote:
 
> The second one, right? So the user of the program can now report this
> error and fix. But if the use gets 0, then they think all is fine and
> they might try to find the error from other place later on.
 
In some situations, that might make it easier to spot the problem. In
other situations, it is far worse. Suppose this is code in your
internet-enabled fridge, which is measuring the average amount of coke
you drink so that it can pre-order enough for your expected needs next
month. If you don't drink coke, and it is averaging an empty set, would
you rather your fridge ordered 0 cokes for next month, of 99999999999999
bottles?
 
If you are writing a general function without knowing /all/ of its
usage, then you do not have any basis for saying that returning
"max_double" is somehow "better" than returning 0. If the user puts in
incorrect data, then your result will /always/ be wrong - no matter what
you return. It is /always/ the function user's responsibility to pass
correct data to a function.
JiiPee <no@notvalid.com>: Jan 13 11:36AM

On 13/01/2017 11:06, David Brown wrote:
> month. If you don't drink coke, and it is averaging an empty set, would
> you rather your fridge ordered 0 cokes for next month, of 99999999999999
> bottles?
 
But I would not code it like that. I would do like this:
avCoke = average(..);
if(avCoke > 9999)
something_is_wrong_so_report_about_this();
else
orderCokes();
 
so i would check that value *before action*. The problem with 0 is that
even if we are checking it it does not raise any concerns as it is a
valid value (zero cokes looks just fine ... but would be wrong here).
 
This was my whole idea, that we check the value *before doing action*.
So odd values can be identified.
 
 
> If you are writing a general function without knowing/all/ of its
> usage, then you do not have any basis for saying that returning
> "max_double" is somehow "better" than returning 0.
 
It might be better in a way that it causes "more mess" so its more
detectable. 0 does not normally cause any doubts (unless a pointer
value). Thats why I chose max-values if I have to chose an error value.
Many C-programmers say the same: "its good that the program crashes so
we can find the error and fix it". In a way it makes sense sometimes.
Its better that the program crashes rather than that it causes damage is
not noticed.
 
But it also depends on where its used. Obviously if its about cars speed
we might prefer to return 0 rather than make the car go max speed. But
when debugging its easier to find the bug if I get a value 999999999999.
 
> If the user puts in
> incorrect data, then your result will/always/ be wrong - no matter what
> you return.
 
but the difference is that with 0 we dont find out that the result was
wrong but with 9999999999 we will more easily see that the result is wrong.
 
> It is/always/ the function user's responsibility to pass
> correct data to a function.
 
We are talking here if that fails... so security after that.
David Brown <david.brown@hesbynett.no>: Jan 13 01:12PM +0100

On 13/01/17 12:36, JiiPee wrote:
> valid value (zero cokes looks just fine ... but would be wrong here).
 
> This was my whole idea, that we check the value *before doing action*.
> So odd values can be identified.
 
If you check the value /before/ doing action, then you would check the
size of the set before finding the average, and thus write /correct/ code.
 
What you are asking is for a way to call a function with "garbage in,
garbage out", and somehow distinguish the resulting "garbage out".
 
And I would far rather that my fridge ordered 99999999999999 bottles of
coke - because the shop would refuse the order and tell me my fridge is
broken. If it ordered 9999 bottles, the shop might just think I was
planning a huge party.
 
Your example here simply demonstrates that there is /no/ good choice of
a value that you can return that indicates a failure. If you want to
indicate a failure, you need to do it with a /specific/ and /explicit/
mechanism - such as an exception, or returning a <success, value> pair.
If you are willing to accept that the function user's mistake is the
function user's problem, then returning 0 is just as good as any other
value, because /all/ other values could cause problems for badly written
code, just as 0 could.
 
 
>> It is/always/ the function user's responsibility to pass
>> correct data to a function.
 
> We are talking here if that fails... so security after that.
 
You /cannot/ fix the broken function user's code from within /your/
function. You can somewhat reduce the risk of further damage, and you
can sometimes make it easier to debug the problem, but that is all.
There are times when the /best/ thing to do when detecting bad input is
to crash the program with an error message - and times when that is the
/worst/ think to do.
 
Please understand this, and stop trying to come up with different return
values and different circumstances. There is /no/ correct answer here.
If people pass invalid input to a function, you cannot give a sensible
result. You may /specify/ a given result for a given input, in which
case that input is no longer valid - but it is again up to the
function's user to understand what the function does.
 
This has been understood since the beginning of programmable computers
some 200 years ago, and is just as true today:
 
<https://www.brainyquote.com/quotes/authors/c/charles_babbage.html>
JiiPee <no@notvalid.com>: Jan 13 01:11PM

On 13/01/2017 12:12, David Brown wrote:
>> So odd values can be identified.
> If you check the value /before/ doing action, then you would check the
> size of the set before finding the average, and thus write /correct/ code.
 
it depends... Lets think about situation where the user observes values
printed on the screen and acts upon it. In that case we do not have any
checks in the code, but the user checks the values by looking at the
screen. IN this situation average value: 99999999999 printed on the
screen surely would be better than 0, isnt it?
 
 
> What you are asking is for a way to call a function with "garbage in,
> garbage out", and somehow distinguish the resulting "garbage out".
 
yes. If the console prints: "999999999999" its easy for the user to spot it.
 
> coke - because the shop would refuse the order and tell me my fridge is
> broken. If it ordered 9999 bottles, the shop might just think I was
> planning a huge party.
 
well that was only an example... we can have:
if (> 9999999999)
 
And no code should be made to order automatically any number of cokes...
of course the program would need to check how many cokes are ordered. OR
course there are many checks that there is a limit how much can be
ordered. No sane program would allow to order 999999999 cokes.
 
> Your example here simply demonstrates that there is /no/ good choice of
> a value that you can return that indicates a failure.
 
but if the user sees the value on a screen, 999999999 is easier to spot
than 0, isnt it?
 
> function user's problem, then returning 0 is just as good as any other
> value, because /all/ other values could cause problems for badly written
> code, just as 0 could.
 
but in many cases 9999999999999999 is easier to spot than 0, isnt it?
like if the values are printed on the screen (which they are in many
programs).
 
> values and different circumstances. There is /no/ correct answer here.
> If people pass invalid input to a function, you cannot give a sensible
> result.
 
but even with pointers.... if we cannot put any sensible value, we
normally want to put NULL, because its easier to find that error rather
than put an address which points to an object which does not exist. When
debugging, NULL value is easier to spot than some valid/invalid object
address value.
 
I dont know, I dont feel like returning 0 in average() if there was an
error, beacause that might confuse to think everything is fine....
Paul <pepstein5@gmail.com>: Jan 12 05:54PM -0800

In the below code, I'm unclear as to what Data result = {} does. Is this
the same as Data result = Data();
After the line Data result = {}; are the values of bytes all equal to 0,
or are they garbage values? I'm thinking garbage values but I'm not sure.
Many thanks for your help.
Paul
 
 
struct Data {
char bytes[16];
};
 
Data f() {
Data result = {};
// generate result
return result;
}
 
int main() {
Data d = f();
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 13 07:18AM +0100

On 13.01.2017 02:54, Paul wrote:
> In the below code, I'm unclear as to what Data result = {} does. Is this
> the same as Data result = Data();
 
Yes, in the sense of having the same effect in this case.
 
 
> After the line Data result = {}; are the values of bytes all equal to 0,
 
Yes.
 
> or are they garbage values?
 
No.
 
 
 
> int main() {
> Data d = f();
> }
 
Cheers,
 
- Alf
Paul <pepstein5@gmail.com>: Jan 13 03:45AM -0800

On Friday, January 13, 2017 at 6:19:19 AM UTC, Alf P. Steinbach wrote:
> > }
 
> Cheers,
 
> - Alf
 
Many thanks,
 
Paul
"Chris M. Thomasson" <invalid@invalid.invalid>: Jan 12 03:26PM -0800

On 1/10/2017 12:57 AM, Alf P. Steinbach wrote:
 
>> Structured bindings have nothing to do with "returning multiple values
>> from a function".
 
> Forks have nothing to do with eating.
 
Should there be corks on the end of the forks to prevent somebody from
coding something with bugs, where the fork might just have the ability
to harm another entity?
 
Ahh, the beauty of C and/or C++. You can drive right off a cliff, just
like in real life; but we are sill here as long as some rules are
followed. Here is a possible model to follow:
 
http://www.stroustrup.com/JSF-AV-rules.pdf
 
;^)
"Chris M. Thomasson" <invalid@invalid.invalid>: Jan 12 03:36PM -0800

On 1/10/2017 12:04 PM, Stefan Ram wrote:
 
> One variant might be:
 
> static void escape( void * p )
> { asm volatile( "" : : "g"(p) : "memory" ); }
 
Not sure what the purpose of this compiler barrier in a function serves
as of now. But, I would call a single compiler barrier with release
memory visibility semantics _after_ setting my state, and _before_
making it _visible_ to any other thread/process.
 
 
> int a = av.a(); escape( &a );
> int b = av.b(); escape( &b );
> int c = av.c(); escape( &c ); }
 
Nice! I was focusing on the decomposition of a free-function wrt its
input/output parts, in the form of POD structs. This is fine though.
 
Thanks.
 
 
 
> by
 
> input i; i.horizontal = 1; i.vertical = 2;
 
> . (Of course not meaningless names such as »a« or »b«.)
 
Its more verbose, but fine; no problem. :^)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 13 07:11AM +0100

On 13.01.2017 00:26, Chris M. Thomasson wrote:
> followed. Here is a possible model to follow:
 
> http://www.stroustrup.com/JSF-AV-rules.pdf
 
> ;^)
 
Well, they made a mess of things, but why?
 
I am ~100% sure that a main problem is that they thought they could
replace intelligence with mechanical rules. For example, the rule that
one should not use `errno` is only meaningful for a dumb programmer who
would use that to communicate failures from his own code. But what is
the result of using dumb programmers to create the system?
 
Oh, we've seen the result. :(
 
 
Cheers!,
 
- Alf
"Chris M. Thomasson" <invalid@invalid.invalid>: Jan 12 07:50PM -0800

This is about using aggregate initialization in the constructor of a
struct/class that has an array. Basically, I am wondering if the
following code wrt the constructor of foo is kosher:
______________________________________________
#include <cstdio>
 
 
struct foo
{
struct inner
{
unsigned int a;
unsigned int b;
};
 
inner inner[3];
unsigned int a;
unsigned int b;
 
foo(
unsigned int a_inner,
unsigned int b_inner
): inner {
{ a_inner, b_inner },
{ a_inner + 1, b_inner + 2 },
{ a_inner + 3, b_inner + 4}
},
a(a_inner + b_inner),
b((a_inner + b_inner) / 2)
{
 
}
};
 
 
int main()
{
{
foo f(3, 5);
 
std::printf("f.inner[0].a:(%u)\nf.inner[0].b:(%u)\n",
f.inner[0].a, f.inner[0].b);
 
 
std::printf("f.inner[1].a:(%u)\nf.inner[1].b:(%u)\n",
f.inner[1].a, f.inner[1].b);
 
 
std::printf("f.inner[2].a:(%u)\nf.inner[2].b:(%u)\n",
f.inner[2].a, f.inner[2].b);
 
std::printf("f.a:(%u)\nf.b:(%u)\n", f.a, f.b);
}
 
return 0;
}
______________________________________________
 
Seems to work fine for me.
Jeff-Relf.Me <@.>: Jan 12 04:06PM -0800

benj <benj@nobody.net>: Jan 12 08:41PM -0500

On 1/12/2017 7:06 PM, Jeff-Relf.Me wrote:
> Capitalism and/or Communism, it doesn't matter;
> either way, the fit thrive and idiots die.
 
> My userContent.CSS(.TXT) <http://Jeff-Relf.Me/userContent.CSS.TXT>, for Mozilla FireFox.
 
Actually Comrade, history shows that under communism hundreds of
millions of the fit did not survive. No matter communism didn't survive
either inspite of the best efforts of Hillary and her comrades. You are
a dinosaur, Rolf.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: