Tuesday, December 22, 2015

Digest for comp.lang.c++@googlegroups.com - 17 updates in 7 topics

flimflim1172@gmail.com: Dec 22 09:52AM -0800

On Friday, December 18, 2015 at 10:13:07 PM UTC-7, Öö Tiib wrote:
> too fast ... so the convenience does give next to no returns. IDEs
> that try to be overly helpful and convenient on top of that (like Apple
> Xcode) are becoming outright annoying with that help.
 
I accept that it's unclear to you. C++ is used in so many contexts, I really can't everyone else to get where I'm coming from. Some will, some won't.
 
Not sure how it relates, but 100% agreed on the "help" from tools. I fell in love with MSVS back in the late 90s, in part because of some of that help, but since then it's packed on so much crap I can hardly move around in it freely anymore.

 
> The programming languages are software design tools. There's no
> point whatsoever to change C++ to be exactly like some other programming
> language. People who like C# or lua should use those instead of C++.
 
No argument. I didn't start this discussion with "change it, it's broken". I started it with "please help me understand why it's not broken". David Brown did exactly that.
 
I personally edit your "people who like C# or lua" to "people who need C# or lua".
 
 
 
> > That's not my issue either. I am neither unwilling to write local
> > "int x = 0", nor am I unsure where I am required to initialize member x_.
 
> In C++ you are not required to initialize anything.
 
This entire thread is about initializing, and why it is or isn't better for built-ins to be initialized to zero by default. No one is advocating that the option to leave uninitialized be taken away. It's a very important feature of the language.
 
> > specific contexts, and I accept that the suggestion of "int x is zero
> > unless stated unspecified" would do just that.
 
> In C++ int is zero when it is stated to be zero.
 
and when declared with static storage, FYI.
 
> > are very new ground for me.
 
> If you need some sort of language to sit somewhere then put it to sit
> there.
 
Good advice.
flimflim1172@gmail.com: Dec 22 10:20AM -0800

On Saturday, December 19, 2015 at 1:29:34 AM UTC-7, mark wrote:
> to forget an initialization somewhere and the infrastructure for
> tracking that down is far from perfect. Security bugs from using
> uninitialized variables are quite common.
 
I think we find ourselves in a similar camp but for different reasons. I'm quite comfortable that I have enough tools to catch mistakes where I should have initialized and didn't (maybe I refactored the code and broke initialization, or I just plain forgot).
 
To me it's mostly an ergonomics issue, and only when I'm writing certain types of code that one might generalize as high-level scripting. Situations that are highly iterative and produce tons of code fast. I think I'm on a shrinking island of people who still use C++ this way. In these particular coding situations, the time it takes to visit the initialization sites shows up in my assessment of "what is measurably throttling my progress", and so I'd prefer the language to assign zero to int by default rather than some unknown-yet-still-valid value, the same way it assigns zero size to vector<int> by default rather than some unknown-yet-still-valid size.
 
This thread has convinced me that this is one of the lines marking divisions that I've heretofore refused to believe exist: Divisions between what C++ is good for and what Rust/D/others are good for.
flimflim1172@gmail.com: Dec 22 10:50AM -0800

On Sunday, December 20, 2015 at 10:51:33 AM UTC-7, Jorgen Grahn wrote:
 
> --
> // Jorgen Grahn <grahn@ Oo o. . .
> \X/ snipabacken.se> O o .
 
In highly iterative code, every time I use a std library type or one of my own types I am grateful I don't have to visit an initialization site before visiting the implementation site. Very often though, I truly have an int or a bool, not a counter<> or some other widget<>. It has crossed my mind more than once before to make "class Int" and "class Bool" to use in this type of script-y code. Perhaps I'm being too curmudgeonly here, but the very thought makes me nauseous.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 11:56PM +0100

> I've long wished C++ worked a bit like this:
 
> int x; // initialized to zero in all scopes (not just global)
 
> int y = std::undefined; // it's left uninitialized, only when I say so
 
This is a good idea, and you're not the first to air it.
 
A simple but unfortunately verbose interim solution is to define a
wrapper like this:
 
struct Not_initialized {};
 
template< class Type >
struct Initialized_
{
Type value;
Initialized_(): value() {}
Initialized_( Not_initialized ) {} // !
};
 
and e.g. definining
 
using Int = Initialized_<int>;
 
and then you should be able to write
 
Int x; // Inialized to 0.
Int y{ Not_initialized }; // But the = syntax may cause actions.
 
cout << x.value*y.value << endl;
 
Of course the name "value" could be replaced with e.g. just "_" to cut
down on the verbosity.
 
A more extreme measure for more concise code is to implement a basic
type replacement class, i.e. a type with arithmetic operators,
comparison etc. The Boost library has some help for that. In principle
it could be as efficient as direct use of the build-in type it replaces.
 
 
> Foo(std::undefined_t) : x_(std::undefined) { }
> int x_;
> };
 
One way to guarantee initialization of members is to make them "const",
at the cost of losing copy assignment.
 
Another way is to use one of the two wrapper types sketched above.
 
 
> };
 
> Foo foo; // foo.x_ is zero
> Foo foo = std::undefined; // foo.x_ is undefined
 
Well yes, in C++03 it was a problem how to zero-initialize a POD struct
local automatic /variable/.
 
Doing it for dynamic allocation or for a temporary was easy, e.g.
 
Pod* p = new Pod(); // Value-initialized = zero for POD, hurray!
 
But trying that for a local variable, like
 
Pod f();
 
would just declare a function f; it's the infamous "most vexing parse".
 
For a variable one could write
 
Pod o = Pod();
 
but that was very ugly and verbose.
 
Happily with C++11 you can just write
 
Pod o{}; // Yay, braces to the rescue!
 
> really smart people, and so I want to learn from you. If I could
> understand why it's better for built-ins to be undefined by default
> rather than by request, it would be a great help to me.
 
Those who argue that the current rules are bestest are presumably silly
conformists.
 
The current rules were good for early C, where it was the programmer's
job to do micro-optimizations, but they're not good for modern C++.
 
Due to its history C++ has a lot of defaults backwards for modern
programming. For example, it would IMO be much better if objects were
"const" by default, and had to be declared mutable to be, well, mutable.
At one time I also argued that methods (non-static member functions)
should better have been virtual by default, but I'm not so sure now: I
find that my own default now is non-virtual, that for me, now, there
must be a good /reason/ for a method to be virtual.
 
 
> those issues. I instead want to learn why it shouldn't be done even if
> C++ were being designed for the first time today. If I could get that
> through my thick head, I'd be very happy.
 
I agree completely with you, IMO there isn't any technical reason why a
new language today should be like that.
 
I think those who argue otherwise (you indicate that such exist), do it
just out of conformity, a misplaced idea of belonging in a group of
followers of X by strongly denying any slightest blemish of X.
 
On the other hand, retrofitting the zero-initialization on C++, in a way
where one could not opt out of it, could break time-critical code in
e.g. real time systems.
 
 
> std::string x; // well defined
> std::shared_ptr<int> // well defined (empty shared_ptr)
 
> In a perfect world, why should they be different?
 
In a perfect world one would have to explicitly accept the dangers of
the nano-optimization.
 
Btw., the term you're looking for isn't "undefined".
 
It's "indeterminate value".
 
 
> for catching uninitialized data bugs, but I'm not sure why it would
> matter to valgrind whether the lack of initialization was default or
> explicit.
 
A debugger can rely on certain well know bitpatterns indicating most
likely uninitialized variables, e.g. CCCC... hex.
 
The idea is to fill memory with that bitpattern, and detect that it
apparently hasn't been changed in a variable (especially pointer).
 
But arguing that uninitialized variables are good because it allows a
debugger to detect uninitialized variables, is not very convincing...
 
 
Cheers!, & hth.,
 
- Alf
 
PS: Sorry if much of what I wrote here has already been discussed. I've
been offline for a while and there was just too much in this thread.
StuartRedmann <DerTopper@web.de>: Dec 22 07:46AM +0100

On 12/13/15, JiiPee wrote:
>> passing argument to them.
>> But all programming languages have this same problem, so maybe we just
>> have to live with it .
 
 
On 12/13.15, Wouter van Ooijen wrote:
> Named parameter association (Ada, Python, probably others I am not
> famliar with) nicely solves this.
 
> Wouter
 
 
C# has named parameter association, and C# was intended to be a
successor of C++ (although I have no source for this):
 
from http://www.dotnetperls.com/named-parameters:
using System;
 
class Program
{
static void Main()
{
// Call the Test method several times in different ways.
Test(name: "Perl", size: 5);
Test(name: "Dot", size: -1);
Test(6, "Net");
Test(7, name: "Google");
}
 
static void Test(int size, string name)
{
Console.WriteLine("Size = {0}, Name = {1}", size, name);
}
}
 
Regards,
Stuart
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 22 11:05PM +0100

On 12/22/2015 7:46 AM, StuartRedmann wrote:
 
> [snip] C# was intended to be a
> successor of C++ (although I have no source for this):
 
Rather, C# was designed as the primary programming language for the .NET
platform, which apparently co-evolved to support that language.
 
Being designed primarily for a virtual machine, the .NET Common Language
Runtime, C# could never be a successor of C++.
 
Anders Hejlsberg seems to have drawn inspiration both from his work
creating Borland's Turbo Pascal, and creating Microsoft's Java
implementation J++. Early C# might be characterized as a shallow copy of
Java with some pieces of Turbo Pascal freshness and practicality added
here and there. At the time, around 2000, I recommended that students
start learning programming using C#, just as I'd earlier recommended
Turbo Pascal, as a language where they could be productive fast,
including doing GUI stuff in reasonably simple ways.
 
Cheers!, & Happy Christmas (coming up),
 
- Alf
porparek@gmail.com: Dec 22 04:57AM -0800

Hi
 
Is the following typeid comparison correct in all cases ?
typeid(T1) == typeid(T2);
 
or I should rather use:
typeid(T1).hash_code() == typeid(T2).hash_code()
 
thanks for help
"Öö Tiib" <ootiib@hot.ee>: Dec 22 06:43AM -0800

> Hi
 
> Is the following typeid comparison correct in all cases ?
> typeid(T1) == typeid(T2);
 
Yes. The 'std::type_info::operator==' must return true if the T1 and
T2 are same type and false if those are not.
 
 
> or I should rather use:
> typeid(T1).hash_code() == typeid(T2).hash_code()
 
That is worse. We may only trust it when it results with 'false',
when it results with 'true' then we have to make further checks if
it isn't false positive. Avoid it unless it is some sort of performance
optimization.
 
You perhaps were worried that the 'std::type_info' objects referred
by 'typeid' may be different so addresses may not compare equal:
 
const std::type_info& ti1 = typeid(A);
const std::type_info& ti2 = typeid(A);
assert(&ti1 == &ti2); // it is not guaranteed that addresses are same
 
Do not compare addresses of objects what 'typeid' refers and all is fine.
legalize+jeeves@mail.xmission.com (Richard): Dec 22 06:33PM

[Please do not mail me a copy of your followup]
 
porparek@gmail.com spake the secret code
 
>Is the following typeid comparison correct in all cases ?
>typeid(T1) == typeid(T2);
 
An alternative is to use std::is_same<T1, T2>::value.
<http://en.cppreference.com/w/cpp/types/is_same>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
mark <mark@invalid.invalid>: Dec 22 01:52PM +0100

On 2015-12-21 18:05, Jorgen Grahn wrote:
> modify them so normal versions of the standard library are used. Much
> of the templated code will be built without optimization, but at least
> it won't have extra range checks on iterators, operator[] and so on.
 
At least with VC++ it doesn't work. Debug/release builds are not binary
compatible.
 
I definitely want range checking in debug builds. The performance
problem isn't range checking in the first place. The problem is insanely
long call chains that heavily rely on inlining.
"Öö Tiib" <ootiib@hot.ee>: Dec 22 06:03AM -0800

On Tuesday, 22 December 2015 14:52:41 UTC+2, mark wrote:
> > it won't have extra range checks on iterators, operator[] and so on.
 
> At least with VC++ it doesn't work. Debug/release builds are not binary
> compatible.
 
C++ library is mostly header-only, what you mean by binary compatibility?
In VC++ different versions of library code are chosen depending how you
define _SECURE_SCL and _ITERATOR_DEBUG_LEVEL (also _SCL_SECURE_NO_WARNINGS).
Indeed, you have to define those same for whole application, can't
be that you tinker with choice of library versions on per-file basis.
 
 
> I definitely want range checking in debug builds. The performance
> problem isn't range checking in the first place. The problem is insanely
> long call chains that heavily rely on inlining.
 
Those "debug" and "release" are just names for common configurations.
If you need inlining in "debug" builds then enable optimizations in
"debug" builds. If you need debug information in "release" builds then
keep generating that for "release" builds.
johannes.gerd.becker@gmail.com: Dec 22 12:52AM -0800

> that has deeper knowledge of exception throwing mechanics and contains
> some sort of reference counting; 'std::any' is singular container of
> single object of whatever type.
 
Well, but it is (conceptually) simple to implement one in terms of the other. A std::exception_ptr can be thought of as being a std::shared_ptr<std::any>, and std::any can be implemented by abusing a std::exception_ptr, see here:
 
http://stackoverflow.com/questions/34391357/stdany-by-stdexception-ptr
 
> > re-throwing and catching immediately (please correct me if I am wrong).
 
> May be there is come context where that may make sense. What is bad
> about re-throwing and catching?
 
Suppose there is some sub-task which might result in an exception, which is caught and stored as a std::exception_ptr. Now we want to convert potential exceptions into an error code at the caller's side. Does it really make sense to establish a whole try-catch machinery just in order to figure out what kind of exception was thrown, in particular since try/catch is relatively slow and some coding guidelines forbid it? In addition, as soon as there is std::any in the standard, infrastructure will arise for handling std::any. If exception_ptrs are a thing of their own, they will never able to be used together with this infrastructure.
 
Note that if an exception_ptr is convertible to a std::any, it will become possible to do much more useful things in a catch-all clause.
 
> it is the main point of 'std::exception_ptr' ... so someone who finds
> that constructing exceptions is expensive can throw same exception object
> over and over from potentially many threads and potentially at same time.
 
True, I missed that point. Nevertheless, with the current proposal, it will not be possible to throw the *contents* of a std::any unless you know which types it may contain. Throwing a std::any is, however, easy to implement if std::any supports it. Let us assume any is implemented as holding a unique_ptr to a polymorphic holder class any_value. Then you could do something like:
 
struct any {
void throwme () { m_val->throwme(); }
private:
unique_ptr<any_value> m_val;
}
 
struct any_value {
//...
virtual void throwme () = 0;
}

template <class T>
struct any_value<T> : any_value {
//...
void throwme () override { throw m_v; }
 
private:
T m_v;
}
 
This is impossible if std::any does not support it, hence it should be included in the first place.
"Öö Tiib" <ootiib@hot.ee>: Dec 22 05:13AM -0800

> > single object of whatever type.
 
> Well, but it is (conceptually) simple to implement one in terms of the other. A std::exception_ptr can be thought of as being a std::shared_ptr<std::any>, and std::any can be implemented by abusing a std::exception_ptr, see here:
 
> http://stackoverflow.com/questions/34391357/stdany-by-stdexception-ptr
 
The 'exception_ptr' can have alternative underlying storage and mechanics
because exceptions are propagated by alternative mechanics. Exception
handling is optimized to be cheap when exceptions are not thrown for
cost of being expensive when thrown. So exceptions should not be used
as another way of returning (or even storing) of things.
 
 
> Suppose there is some sub-task which might result in an exception,
> which is caught and stored as a std::exception_ptr. Now we want to
> convert potential exceptions into an error code at the caller's side.
 
So why we don't want to throw exceptions that carry error codes?
But OK, lets say we have good reasons.
 
> the standard, infrastructure will arise for handling std::any.
> If exception_ptrs are a thing of their own, they will never able to
> be used together with this infrastructure.
 
The more I think of it the more it feels like danger of throwing moved
from objects or the like.
 
 
> Note that if an exception_ptr is convertible to a std::any, it will become possible to do much more useful things in a catch-all clause.
 
I do not see any safe way to convert a ref-counted pointer into container.
It must involve making a copy of pointed at object into container.
 
> > that constructing exceptions is expensive can throw same exception object
> > over and over from potentially many threads and potentially at same time.
 
> True, I missed that point. Nevertheless, with the current proposal, it will not be possible to throw the *contents* of a std::any unless you know which types it may contain. Throwing a std::any is, however, easy to implement if std::any supports it. Let us assume any is implemented as holding a unique_ptr to a polymorphic holder class any_value.
 
The *contents* of std::any can not be taken out of it, 'any_cast's return
references and it is impossible to throw references. Construct like
'throw *this;' makes copy of this object. It is not good idea to do
lot of chemistry in constrained in unknown ways situations where
exceptions are thrown.
 
You keep conflating a ref-counted pointer that is perhaps anyway
used internally in exception throwing mechanics and a firm container that
is even encouraged not to use dynamic allocations for storing small
objects (that exceptions often are) in it.
bleachbot <bleachbot@httrack.com>: Dec 22 01:23AM +0100

bleachbot <bleachbot@httrack.com>: Dec 22 01:51AM +0100

Ramine <ramine@1.1>: Dec 21 07:24PM -0800

Hello,
 
 
As you have noticed i am a develloper in the field of parallelism,
but i want to ask you for something, as i have noticed that
GCC and C++Builder and i think also Visual C++, don't come
with a scalable memory allocator, so can you help me to port the
Hoard memory allocator to Mingwin 32 bit and 64 bit, actually the hoard
memory allocator comes with a makefile for visual C++ and for GCC for
Linux, but it doesn't come with a makefile for GCC Mingwin for 32 bit
and 64 bit, so i will ask you if you can help me to write a this hoard
makefile for TDM-GCC Mingwin for 32 bit and 64 bit, here is where you
can find the hoard source file:
 
http://plasma.cs.umass.edu/emery/index.php@page=download-hoard.html
 
 
Also if you can help me after that by telling me how must i compile the
C++ source code and how i can link it with the hoard allocator to enable
scalable memory allocation in C++.
 
 
And here is TDM-GCC:
 
http://tdm-gcc.tdragon.net/
 
 
Thank you,
Amine Moulay Ramdane.
Ramine <ramine@1.1>: Dec 21 07:52PM -0800

Hello,
 
Ignore this message, because i have tried to compile Hoard
with tdm-gcc and it didn't compile.
 
 
Thank you,
Amine Moulay Ramdane.
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: