Wednesday, January 1, 2020

Digest for comp.lang.c++@googlegroups.com - 12 updates in 6 topics

Bo Persson <bo@bo-persson.se>: Jan 01 06:49PM +0100

On 2020-01-01 at 17:46, Bonita Montero wrote:
> Is there a way to determine endianess in a constexpr-function
> which might return true for little endian and false for big
> endian? I guess not, but maybe I din't consider a trick here.
 
"Not" is probably the correct answer here, so in C++20 we get
std::endian where the implementation provides the info.
 
https://en.cppreference.com/w/cpp/types/endian
 
 
Bo Persson
Bonita Montero <Bonita.Montero@gmail.com>: Jan 01 06:54PM +0100


> "Not" is probably the correct answer here, so in C++20 we get
> std::endian where the implementation provides the info.
> https://en.cppreference.com/w/cpp/types/endian
 
Where's the support for the DEC PDP-11 and Honeywell 316 endianess???
;-)
David Brown <david.brown@hesbynett.no>: Jan 01 11:21PM +0100

On 01/01/2020 18:54, Bonita Montero wrote:
>> https://en.cppreference.com/w/cpp/types/endian
 
> Where's the support for the DEC PDP-11 and Honeywell 316 endianess???
> ;-)
 
Gone - along with ones' complement integers.
 
If your code is limited to a known set of compilers or platforms, most
have predefined macros that give you the endianness. There are some
header files floating around the web that have checks for a large number
of different toolchains if you don't want to read all the documentation
yourself.
David Brown <david.brown@hesbynett.no>: Jan 01 11:04PM +0100

On 31/12/2019 18:46, Bonita Montero wrote:
>> you to actually look something up, instead of making up your arguments
>> as you go along.)
 
> There are not much, but these are useless:
 
Thanks for making this effort.
 
 
> -Wcomment
>  It's not rare that you first comment out a part with // and
>  then the outer block with /* */. This isn't really a problem.
 
Yes, it is a problem - it is a symptom of disordered code with
inconsistent styling and coding habits. Such code is harder to read -
it is harder to spot mistakes, and harder to maintain correctly.
 
> -Wenum-compare
>  Unscoped enums are in the same namespace so they should be
>  all comparable.
 
In C, there is only one namespace, so it is useful to have this on -
comparing values from different enumeration types is usually an error in
the code. In C++, you are even less likely to want to compare values of
different types, because you are usually aiming for stricter typing. In
gcc, this is enabled by default in C++ - you get this warning even
without -Wall.
 
> -Wmissing-braces
>  That's really a useless aesthetic warning.
 
If this is triggered, you either have a very lazy style of writing
initialisers with a disregard for code clarity and maintainability, or a
bug in the code. I believe a lot of people want a message in either case.
 
> -Wreorder
>  It's very rare that the order of initialization-calls counts.
 
I can't comment on how often it happens, but sometimes the order /does/
matter. It is a bad idea to have code written so that it appears to
work in one order, when in fact it is executed in a different order.
 
> -Wunused-function
>  This would be disturbing if you would have the function in the
>  code for a later purpose.
 
The various "unused" options can often trigger during early development,
but you want them later. Unused code means untested code, which is a
buried bomb waiting for trouble during later changes to the code.
 
> But I agree that the vast majority of -Wall-warnings makes sense.
 
And if you have a particular dislike for any of them, you can disable
them. "-Wall" is a good starting point for a lot of code, but it is not
perfect for all code, and does not cover many other useful warnings
(some of which I think should enabled by default).
 
I use a great many other gcc warnings in my code - many more than are in
-Wall or -Wextra. But I am fully aware that many don't match the needs
of a lot of other programmers. The aim of "-Wall" is that it should be
useful to a substantial proportion of programmers and programs without
warning about code that is intentionally written as it is. It's not
perfect - but it is pretty good.
David Brown <david.brown@hesbynett.no>: Jan 01 11:09PM +0100

On 01/01/2020 01:16, Chris M. Thomasson wrote:
 
>> Are you kidding? -Wall is one of the most basic options one always
>> uses with gcc (together with -Wextra and a bunch of other warning flags).
 
> Heck, what about -ansi and/or -pedantic... ;^)
 
Don't use "-ansi" - it is a misnomer. Use the "-std" option of your
choice. I would always recommend using "-std".
 
If you are writing highly portable code, then "-Wpedantic" along with a
suitable choice of "-std" is recommended. But not all code is supposed
to be highly portable. If you are writing code with the intention of
using only gcc, then there is no problem using "-std=gnu++17", or
whatever you want, and using gcc extensions. It won't be standard C++,
but you can take advantage of the extensions provided - this is your
choice when you write your code.
 
(There are many other commonly used options, like "-O2" or "-o" to give
the output file name. But -Wall is still a very commonly used standard
option.)
 
 
David Brown <david.brown@hesbynett.no>: Jan 01 11:15PM +0100


>>> Many? As I've asked in another post - name a single one that doesn't.
 
>> I don't know if there are any that don't support it.
 
> Thats because there arn't any because all C++ compilers are also C compilers.
 
MSVC doesn't support modern C.
 
Anyway, compilers support different languages - and they support the
semantics of the language they are using at the time. When you use gcc
to compile C++ code, it uses C++ semantics. When you use it for C code,
it uses C semantics. (And when you use it for Fortran, or Ada, it uses
those language semantics.)
 
>> there is no justification for claiming it applies to all.
 
> Variable length C99 arrays arn't in the C++ standard but I've yet to come
> across a C++ compiler that didn't support them either.
 
gcc doesn't support them when you use it in standard modes.
Manfred <noname@add.invalid>: Jan 01 06:15PM +0100

On 1/1/2020 7:32 AM, Andrew Z wrote:
> outlet.OutletCallback,
> outlet.GetCycleTicks );
> why is the outlet.GetCycleTicks is considered to be a pointer, but the eventGroup is not?
 
eventGroup is declared as
 
> EventGroupHandle_t eventGroup;
 
So, it is an object, not a pointer.
 
 
> changing outlet.GetCycleTicks to outlet.GetCycleTicks() or a number doesn't change the compile time error. I'm still digesting what Alf said above...
 
This is not surprising, all of OutletToggleTask, OutletCallback and
GetCycleTicks are non-static member functions that are used invalidly,
although for different reasons.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 01 10:48PM +0100

On 01.01.2020 08:03, Andrew Z wrote:
> }
 
> i started writing this code with free functions, when i realized that i can wrap all these functions into an objects and have the concise and clean code... well, best plans of mice and men...
 
> not sure what to do....
 
It depends on whether the callback mechanism is your own or provided by
the API you're using (I'm not familiar with the Arduino environment).
 
If it's not your own then presumably the `void*` parameter of the
callback is intended to pass an object pointer. In that case you provide
that object pointer when you install the callback. And so you'll need to
pass that down to the code that installs the callback.
 
 
--------------------------------------------------------------------------
template< class T > using Type_ = T;
 
namespace c_style_api {
extern "C" using Callback = void( void* p_state, const char*
something );
 
extern "C"
void enumerate_something( const Type_<void*> p_state, const
Type_<Callback*> f )
{
f( p_state, "Look, it's " );
f( p_state, "calling back!" );
}
}
 
#include <string>
using std::string;
 
struct Something
{
int m_i;
string m_s;
 
void callback( Type_<const char*> s )
{
m_s += s;
}
};
 
extern "C"
void something_cb( const Type_<void*> p_state, const Type_<const char*> s )
{
reinterpret_cast<Something*>( p_state )->callback( s );
}
 
#include <iostream>
using std::cout, std::endl;
auto main()
-> int
{
Something smth = {};
c_style_api::enumerate_something( &smth, something_cb );
cout << smth.m_s << endl;
}
--------------------------------------------------------------------------
 
 
If it's your own callback, however, then you can simply switch from C
function pointer to C++ `function<void()>` (from the <functional>
header), and use a lambda that captures a reference to your object:
 
 
--------------------------------------------------------------------------
#include <functional>
using std::function;
 
template< class T > using Type_ = T;
 
namespace api {
using Callback = void( const char* something );
 
void enumerate_something( const function<Callback> f )
{
f( "Look, it's " );
f( "calling back!" );
}
}
 
#include <string>
using std::string;
 
struct Something
{
int m_i;
string m_s;
 
void callback( Type_<const char*> s )
{
m_s += s;
}
};
 
#include <iostream>
using std::cout, std::endl;
auto main()
-> int
{
Something smth = {};
api::enumerate_something( [&](auto s){ smth.callback( s ); } );
cout << smth.m_s << endl;
}
 
 
--------------------------------------------------------------------------
 
 
Or alternatively, in C++03 style you can use an interface with a known
virtual function. In that case your object's class needs to implement
the relevant interface.
 
 
--------------------------------------------------------------------------
template< class T > using Type_ = T;
 
namespace api {
// The pure interface class, C++03 style callback:
struct Event_handler{ virtual void on_some_event( const char*
something ) = 0; };
 
void enumerate_something( Event_handler& o )
{
o.on_some_event( "Look, it's " );
o.on_some_event( "calling back!" );
}
}
 
#include <string>
using std::string;
 
struct Something:
api::Event_handler
{
int m_i;
string m_s;
 
void on_some_event( Type_<const char*> s ) override
{
m_s += s;
}
};
 
#include <iostream>
using std::cout, std::endl;
auto main()
-> int
{
Something smth = {};
api::enumerate_something( smth );
cout << smth.m_s << endl;
}
--------------------------------------------------------------------------
 
 
- Alf
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 01 07:24PM

Undefined behaviour aside is C++ union type punning an acceptable hack or not, given that it is legal in C?
If it works on all the compilers I care about does it really matter that it is *currently* classed as undefined behaviour?
I would say that everyone has "secretly" fucking done it some time or other so the C++ Standards Committee should get there act together and legalize it like it has been in C.
Can anyone provide a straight answer to this?
 
/Flibble
 
--
"Snakes didn't evolve, instead talking snakes with legs changed into snakes." - Rick C. Hodgin
 
"You won't burn in hell. But be nice anyway." – Ricky Gervais
 
"I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais
 
"Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Byrne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say."
Ben Bacarisse <ben.usenet@bsb.me.uk>: Jan 01 05:33PM


> Don't use the simpler algorithms. Algthough they might be faster
> on a few elements, their runtime doesn't count then because there
> are just a few elements.
 
But there might be billions of such small sorts. It's a rare situation,
but it shows that the logic you used is not sound.
 
--
Ben.
Manfred <noname@add.invalid>: Jan 01 06:10PM +0100

On 1/1/2020 5:30 AM, James Kuyper wrote:
> that are independent of how null pointers are represented, it would seem
> very odd if that version of C++ was defined in a way which did depend
> upon the representation.
 
FWIW, the current (fourth) edition says (§7.2.2):
"Before nullptr was introduced, zero (0) was used as a notation for the
null pointer.
...
No object is allocated with the address 0, and 0 (the all-zeros bit
pattern) is the most common representation of nullptr. Zero (0) is an
int. However, the standard conversions (§10.5.2.3) allow 0 to be used as
a constant of pointer or pointer-to-member type."
 
AFAICT, other references to nullptr do not make assumptions on the
representation of the null pointer.
 
Note that §10.5.2.3 says that "A constant expression (...) that
evaluates to 0 can be implicitly converted to a null pointer of any
pointer type." and an example is given:
 
int* p = (1+2)*(2*(1-1)); // OK, but weird
 
"Prefer nullptr (§7.2.2)."
 
So, implicit conversion is not restricted to the integer literal 0
(although anything else than nullptr is in fact deprecated).
James Kuyper <jameskuyper@alumni.caltech.edu>: Jan 01 12:21PM -0500

On 1/1/20 12:10 PM, Manfred wrote:
> pattern) is the most common representation of nullptr. Zero (0) is an
> int. However, the standard conversions (§10.5.2.3) allow 0 to be used as
> a constant of pointer or pointer-to-member type."
 
That's not the most important issue. What does it say about:
1. Unary ! as applied to pointer values.
2. Conversion of pointer values to bool.
3. How if-conditions are interpreted.
 
 
> "Prefer nullptr (§7.2.2)."
 
> So, implicit conversion is not restricted to the integer literal 0
> (although anything else than nullptr is in fact deprecated).
 
Yes, that's a fairly recent change in the C++ standard - it used to
allow any integer constant expression with a value of 0, just like C
(though the C++ standard's definition of integral constant expressions
was slightly different from C's definition of integer constant expressions).
 
Of course, (i-j), where i and j are variables that just happen to
currently be equal, has never qualified, under any version of either
standard.
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: