Saturday, February 20, 2016

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

ram@zedat.fu-berlin.de (Stefan Ram): Feb 20 06:21PM

I have observed that in GCC 5.1.1 the following will give »x«
the type »int«
 
auto x { 10 };
 
and the following is forbidden
 
auto x { 10, 12 };
 
. In GCC 4.9.2, however,
 
auto x { 10 };
 
gives »x« the type »initializer_list« and
 
auto x { 10, 12 };
 
is allowed.
 
AFAIK, GCC 4.9.2 thus better implements C++11 and C++14.
 
So, GCC 5.1.1 might still be buggy (it seems to be an early
release) or it might already try to implement C++17.
 
Does anyone here know whether the GCC 5.1.1 behavior is indeed
intended for C++17?
ram@zedat.fu-berlin.de (Stefan Ram): Feb 20 06:28PM

>Does anyone here know whether the GCC 5.1.1 behavior is indeed
>intended for C++17?
 
Found this in 7.1.6.4 in both N4431 and N4567, but not in N3376
 
auto x5{ 3 }; // decltype(x5) is int
 
. So, this is C++17, but not C++14?
ram@zedat.fu-berlin.de (Stefan Ram): Feb 20 11:31PM

#include <iostream>
constexpr double operator "" ²( long double const d ){ return d*d; }
int main(){ ::std::cout << 3.00² << '\n'; }
[Error] stray '\262' in program
 
Alas, the compiler is right. Still, it would have been nice, if
the program would just have printed »9«. What's working is:
 
#include <iostream>
constexpr double operator "" _2( long double const d ){ return d*d; }
int main(){ ::std::cout << 3.00_2 << '\n'; }
 
The following also does not work:
 
#include <iostream>
#include <cmath>
 
constexpr double operator ^
( double const x, double const y )
{ return ::std::pow(x,y); }
 
int main(){ ::std::cout << 3.00 ^ 2.00 << '\n'; }
 
Of course, the compiler is right, but the committee could have
said: Ok, we reserve »^« for integral types, but the user can
overload it for floating-point types. (It still would not have
the right priority and associativity.)
wander <wandersys@gmail.com>: Feb 20 06:48AM -0800

Good day!
So, let me a little bit simplify the question, making it more concrete.
 
Let`s see:
template <typename T>
struct test
{
typedef void(* type)(T);
};
 
typedef void foo_t() const;
 
typedef test<foo_t>::type func_t;
 
Is this code is correct according the standard C++11(14)?
I mean that there are two rules that now (in my opinion) contradict each other.
 
The first rule is (last draft):
8.3.5/5
"The type of each parameter (including function parameter packs) is determined from its own decl-specifier-seq and declarator.
After determining the type of each parameter, any parameter of type "array of T" or "function returning T" is
adjusted to be "pointer to T" or "pointer to function returning T", respectively."
 
The second rule is (last draft):
8.3.1/4
"Forming a pointer to function type is ill-formed if the function type has cv-qualifiers or a ref-qualifier."
 
This question has arisen because that all modern compilers can add a pointer to cv-qualified function type despite
the prohibition without any problems.
Example(clang): http://melpon.org/wandbox/permlink/79tqlLHKIkSdamtv
Example(vs13): http://rextester.com/RWX2579
Example(gcc): http://melpon.org/wandbox/permlink/PlGbEzpWCjSeapuw
 
Maybe there is some kind of exception?
Background of my initial question somehow comes to this.
 
Also interested in the same question in the context of C++03, where there is no equally clear statements about this case.
 
Thank you again.
"Öö Tiib" <ootiib@hot.ee>: Feb 20 10:56AM -0800

On Saturday, 20 February 2016 16:48:53 UTC+2, wander wrote:
 
> typedef void foo_t() const;
 
> typedef test<foo_t>::type func_t;
 
> Is this code is correct according the standard C++11(14)?
 
It likely is not. The 'foo_t' there is sort of half-type.
A function type with a cv-qualifier-seq or a ref-qualifier (including a
type named by typedef-name (7.1.3, 14.1)) shall appear only as:
 
the function type for a non-static member function,
the function type to which a pointer to member refers,
the top-level function type of a function typedef declaration or alias-declaration,
the type-id in the default argument of a type-parameter (14.1), or
the type-id of a template-argument for a type-parameter (14.3.1).
 
The 'func_t' however is pointer to function type where it seems to appear
as type of function parameter. I do not understand how such function
type is valid.
 
 
 
> The second rule is (last draft):
> 8.3.1/4
> "Forming a pointer to function type is ill-formed if the function type has cv-qualifiers or a ref-qualifier."
 
Your function type to what you form a pointer does not have cv-qualifiers
or ref-qualifiers, it has a parameter that is function type with
cv-qualifier.
 
> Background of my initial question somehow comes to this.
 
> Also interested in the same question in the context of C++03, where there is no equally clear statements about this case.
 
> Thank you again.
 
Not sure, may be they are preparing some sort of concepts lite with what
what you are trying to do there makes sense somehow. Or it may be I am
confused and misunderstand something obvious.
wander <wandersys@gmail.com>: Feb 20 12:15PM -0800

> The 'func_t' however is pointer to function type where it seems to appear
> as type of function parameter. I do not understand how such function
> type is valid.
 
I understand your point.
 
 
> Your function type to what you form a pointer does not have cv-qualifiers
> or ref-qualifiers, it has a parameter that is function type with
> cv-qualifier.
 
I know. 8.3.5/5 says that the function type acquires pointer properties (as an argument of another function), but function type with cv-qualifier-seq can not be a pointer itself. At least the user can't do it (adding pointer explicitly won't compile).
So you say code posted before is not valid. And it should not compile. But it's compiled anywhere. That's why I think there are some non-trivial exception. Or we have a bug in all compilers?
 
Thanks for response.
"Öö Tiib" <ootiib@hot.ee>: Feb 20 04:30AM -0800

On Friday, 19 February 2016 22:08:05 UTC+2, Marcel Mueller wrote:
 
> gui/dialog.cpp: In constructor `UrlDialog::UrlDialog(long unsigned int,
> const char*)':
> gui/dialog.cpp:177: error: parse error before `.' token
 
That is embarrassing but I can't see what is wrong without that +.
Are there some sort of macros or templates that screw it up somehow?
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 20 03:07PM +0100

On 20.02.2016 13:30, Öö Tiib wrote:
>> gui/dialog.cpp:177: error: parse error before `.' token
 
> That is embarrassing but I can't see what is wrong without that +.
> Are there some sort of macros or templates that screw it up somehow?
 
Most vexing parse.
 
Cheers & hth.,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Feb 20 06:45AM -0800

On Saturday, 20 February 2016 16:08:07 UTC+2, Alf P. Steinbach wrote:
 
> > That is embarrassing but I can't see what is wrong without that +.
> > Are there some sort of macros or templates that screw it up somehow?
 
> Most vexing parse.
 
But how? Trying to manufacture some dummies here does not reveal the issue:
 
#include <iostream>
#include <string>
 
using HWND = int const*;
 
HWND GetHwnd() {return nullptr;}
 
struct ControlBase
{
explicit ControlBase(HWND) {}
void Text( std::string const& t) {std::cout << t << std::endl;}
};
 
int main()
{
std::string title {"works"};
// No + ... but compiler does parse.
ControlBase(GetHwnd()).Text(title);
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Feb 20 05:01PM +0100

On 20.02.2016 15:45, Öö Tiib wrote:
> // No + ... but compiler does parse.
> ControlBase(GetHwnd()).Text(title);
> }
 
This seems to be a gray area, because Visual C++ 2015 and g++ 5.1 differ
in their opinion of almost identical source code:
 
#include <iostream>
#include <stddef.h>
#include <string>
 
typedef int const* HWND;
 
HWND GetHwnd() {return NULL;}
 
struct ControlBase
{
explicit ControlBase(HWND) {}
void Text( std::string const& t) {std::cout << t << std::endl;}
};
 
int main()
{
std::string title = "works";
// No + ... g++ accepts it, but MSVC issues compilation error.
ControlBase(GetHwnd()); //.Text(title);
}
 
g++ 5.1.0 accepts it, while Visual C++ 2015 produces this compilation error:
 
> foo.cpp(19): error C2556: 'ControlBase GetHwnd(void)': overloaded function differs only by return type from 'HWND GetHwnd(void)'
> foo.cpp(7): note: see declaration of 'GetHwnd'
> foo.cpp(19): error C2040: 'GetHwnd': 'ControlBase (void)' differs in levels of indirection from 'HWND (void)'
 
 
This indicates to me that it's /possible/ to parse the first part as a
function declaration. Adding a unary `+` removes the MSVC error. And so
I conclude that the most vexing parse is involved for the modified code,
and somehow -- unspecified -- was the reason for original error.
 
 
Cheers & sorry for not having the whole story,
 
- Alf
Ian Collins <ian-news@hotmail.com>: Feb 20 01:16PM +1300

Wouter van Ooijen wrote:
>> of TDD you should *literally* do them when learning TDD. You should
>> obey those rules literally and without deviation. Doing so is crucial
>> to learning TDD and actually "getting it" IMO.
 
<snip>
 
> I'll have to choose, upfront, based on what I see, waht is worth trying.
> You (Richard) and Ian present two rather different views of what you
> think TDD is (or should be).
 
I don't think there is as big a difference as you make out. I agree
with Richard that strict adherence to the rules is important in a
teaching environment, whether they be learning a process or anything else.
 
Things were a little different for us when we starting down the XP path.
There weren't any coaches or formal training here at the time, we were
early adopters so we had to find our own way on a real project. We
probably took way longer than if we had had outside support, but we were
happy with the end result. I think we would have failed if we had tried
to do things by the book because we wouldn't have had a good enough
understanding of it! I would probably have had a revolt on my hands...
 
The martial arts analogy is a good one, although I prefer to think of a
development team as a herd of elephants and a good coach as the
matriarch. We didn't have a matriarch, so we blundered around a bit.
But we found the water in the end...
 
> talks, I reject the Bob/Richard path as rediculous, but the
> Ian/Kent-Beck path might be interesting. I'll watch a few Kent Beck
> talks before I decide.
 
Do, the more perspectives you hear, the mode chance there is of hearing
one that fits your way of working.
 
--
Ian Collins
Wouter van Ooijen <wouter@voti.nl>: Feb 20 09:07AM +0100

Op 20-Feb-16 om 1:16 AM schreef Ian Collins:
 
> I don't think there is as big a difference as you make out. I agree
> with Richard that strict adherence to the rules is important in a
> teaching environment, whether they be learning a process or anything else.
 
But, as I understand (both of you, correct me if I am wrong) the rules
that Richard wants to be followed strictly *exclude* refactoring, while
Ians rules *include* it. For me that's the difference between night and day.
 
I don't believe in doing it differently while learning than while doing
actual work. That is OK for muscle work (wax on, wax off), or for
accosciative creativity (which is almost muscle work), but not for
thinking processes. For me, any method that, while in the learning
phase, can't or doesn't want to explain and defend the steps (or absense
of steps!) in terms of the end goal is out. I am not a child, and
neither are my students.
 
Richard, the same UART case for you: I must write a UART baudrate
initialization. The method accepts a run-time specified baudrate. Strict
3-rule TDD keeps me in the cycle
 
- write test case (for a specific baudrate)
- adapt code to pass that case
 
This leads to code that has a list of if's or equivalent. It passes all
the tests, but it is crappy code. Now Ian says: refactor! You seem to
say: no, don't do that. So how does your process lead me to good code?
 
Wouter van Ooijen
Ian Collins <ian-news@hotmail.com>: Feb 20 09:17PM +1300

Wouter van Ooijen wrote:
 
> But, as I understand (both of you, correct me if I am wrong) the rules
> that Richard wants to be followed strictly *exclude* refactoring, while
> Ians rules *include* it. For me that's the difference between night and day.
 
Someone must be misinterpreting something here, TDD without refactoring
is like a burger without a bun: messy!
 
> I don't believe in doing it differently while learning than while doing
> actual work.
 
When learning (especially without a wise head to guide you) how do you
know what is safe to leave out? If you were learning to fly from a
book, would you disregard sections you don't like?
 
> phase, can't or doesn't want to explain and defend the steps (or absense
> of steps!) in terms of the end goal is out. I am not a child, and
> neither are my students.
 
I don't think any one was suggesting that and I think it stresses my
earlier point - hire a coach.
 
 
> This leads to code that has a list of if's or equivalent. It passes all
> the tests, but it is crappy code. Now Ian says: refactor! You seem to
> say: no, don't do that. So how does your process lead me to good code?
 
I say refactor after each commit and I would be most surprised if
Richard disagreed.
 
--
Ian Collins
Wouter van Ooijen <wouter@voti.nl>: Feb 20 09:53AM +0100

Op 20-Feb-16 om 9:17 AM schreef Ian Collins:
 
> When learning (especially without a wise head to guide you) how do you
> know what is safe to leave out? If you were learning to fly from a
> book, would you disregard sections you don't like?
 
Yes. A better comparison would be learning to fly a simulator, because
doing something wrong writing (my own) software will not kill me. If I
get killed in the simulated fligts I will reconsider my opinion of the
sections I disregarded.
 
>> neither are my students.
 
> I don't think any one was suggesting that and I think it stresses my
> earlier point - hire a coach.
 
Sorry, I won't. IMO an intellectual process that can't be explained in a
book, talk or article is not worth considering.
 
>> say: no, don't do that. So how does your process lead me to good code?
 
> I say refactor after each commit and I would be most surprised if
> Richard disagreed.
 
To quote Richard: "Instead of generalizing, I'm going to say that for
Uncle Bob's rules of TDD you should *literally* do them when learning TDD."
 
Maybe the difference is in "when learning", but that leads me to ask how
I would learn anything (except how to write bad code) when refactoring
is not allowed.
 
Wouter van Ooijen
"Öö Tiib" <ootiib@hot.ee>: Feb 20 04:24AM -0800

On Saturday, 20 February 2016 10:53:09 UTC+2, Wouter van Ooijen wrote:
> > earlier point - hire a coach.
 
> Sorry, I won't. IMO an intellectual process that can't be explained in a
> book, talk or article is not worth considering.
 
I am also unsure about Uncle Bob so I ordered "Clean Code: A Handbook of
Agile Software Craftsmanship" of his. He is likely worth reading even
if I disagree with him.
 
 
> Maybe the difference is in "when learning", but that leads me to ask how
> I would learn anything (except how to write bad code) when refactoring
> is not allowed.
 
For me one major point pro unit testing (when I started) was refactoring.
Refactoring during maintenance does result with major regressions without
unit tests. It likely is some misunderstanding here since Uncle Bob does
do it like all do (https://www.youtube.com/watch?v=y4_SJzNJnXU) and
from video it is hopefully clear how unit tests help there.
It is perhaps unfortunate that his TDD rules forget to mention it.
Wouter van Ooijen <wouter@voti.nl>: Feb 20 02:08PM +0100

Op 20-Feb-16 om 1:24 PM schreef Öö Tiib:
 
> I am also unsure about Uncle Bob so I ordered "Clean Code: A Handbook of
> Agile Software Craftsmanship" of his. He is likely worth reading even
> if I disagree with him.
 
From the tone of his talk I would not consider him worth reading, too
dogmatic for my tase, and his favorite talking style is 'proof by
indoctrination'. I'll stick to Kent Beck, who seems (from a few
youtubes) to be much more pragmatic and to prefer giving arguments.
 
> do it like all do (https://www.youtube.com/watch?v=y4_SJzNJnXU) and
> from video it is hopefully clear how unit tests help there.
> It is perhaps unfortunate that his TDD rules forget to mention it.
 
That is why I am pressing along about what the prponents really mean by
TDD. If it is the three rules and just those I think it is stupid, if it
includes refractoring it is surely worth considering.
 
It is of course totally obvious that having set of (regression) tests
that is cheap to run is almost a prerequisite to refactoring. But that
doesn't automatically require TDD.
 
Wouter van Ooijen
woodbrian77@gmail.com: Feb 19 03:53PM -0800

> investments to 3 times the original amount. So the investment
> would result in between $0 and $3,000, depending on how
> things go for the company.
 
I've decided to increase the amount I'll pay for a
successful reference. I'll pay $3,000 and give a $2,000
investment in Ebenezer Enterprises to someone who helps us
find someone interested in using the C++ Middleware Writer.
I'll pay the $3,000 after working for four months on the
project. Ebenezer Enterprises works to reward investments
to 3 times the original amount. So the investment would
result in between $0 and $6,000, depending on how things
go for the company.
 
Brian
benezer Enterprises
http://webEbenezer.net
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: