Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #70935 > unrolled thread
| Started by | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| First post | 2020-01-01 17:46 +0100 |
| Last post | 2020-01-05 08:38 +0100 |
| Articles | 16 — 8 participants |
Back to article view | Back to comp.lang.c++
Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-01 17:46 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bo Persson <bo@bo-persson.se> - 2020-01-01 18:49 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-01 18:54 +0100
Re: Is there a way to determine endianess in a constexpr-function ? David Brown <david.brown@hesbynett.no> - 2020-01-01 23:21 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Robert Wessel <robertwessel2@yahoo.com> - 2020-01-01 18:26 -0600
Re: Is there a way to determine endianess in a constexpr-function ? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-02 00:47 +0000
Re: Is there a way to determine endianess in a constexpr-function ? Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2020-01-02 22:28 -0500
Re: Is there a way to determine endianess in a constexpr-function ? Siri Cruise <chine.bleu@yahoo.com> - 2020-01-02 19:51 -0800
Re: Is there a way to determine endianess in a constexpr-function ? Öö Tiib <ootiib@hot.ee> - 2020-01-02 23:14 -0800
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 08:31 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 08:43 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> - 2020-01-05 00:51 -0500
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-05 07:43 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-05 08:31 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-05 08:34 +0100
Re: Is there a way to determine endianess in a constexpr-function ? Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-05 08:38 +0100
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-01 17:46 +0100 |
| Subject | Is there a way to determine endianess in a constexpr-function ? |
| Message-ID | <quiidc$qa1$1@news.albasani.net> |
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.
[toc] | [next] | [standalone]
| From | Bo Persson <bo@bo-persson.se> |
|---|---|
| Date | 2020-01-01 18:49 +0100 |
| Message-ID | <h744cjF4glqU1@mid.individual.net> |
| In reply to | #70935 |
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
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-01 18:54 +0100 |
| Message-ID | <quimd9$hek$2@news.albasani.net> |
| In reply to | #70940 |
>> 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 Where's the support for the DEC PDP-11 and Honeywell 316 endianess??? ;-)
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2020-01-01 23:21 +0100 |
| Message-ID | <quj613$6nk$1@dont-email.me> |
| In reply to | #70941 |
On 01/01/2020 18:54, 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 > > 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.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2020-01-01 18:26 -0600 |
| Message-ID | <31eq0f58f4jc0jp7k53p3tfit7tt2hmpoa@4ax.com> |
| In reply to | #70947 |
On Wed, 1 Jan 2020 23:21:23 +0100, David Brown <david.brown@hesbynett.no> wrote: >On 01/01/2020 18:54, 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 >> >> Where's the support for the DEC PDP-11 and Honeywell 316 endianess??? >> ;-) >> > >Gone - along with ones' complement integers. Are byte orders other than the two major ones actually disallowed now (or at least in C++20)? The enum provides at least a small loophole for non-big, non-little endian implorations.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-01-02 00:47 +0000 |
| Message-ID | <87sgkyptu8.fsf@bsb.me.uk> |
| In reply to | #70947 |
David Brown <david.brown@hesbynett.no> writes: > On 01/01/2020 18:54, 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 >> >> Where's the support for the DEC PDP-11 and Honeywell 316 endianess??? >> ;-) >> > > Gone - along with ones' complement integers. Not entirely! An implementation must signal a non-uniform endianness, but it can't, using std::endian alone, say much more about it. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2020-01-02 22:28 -0500 |
| Message-ID | <1yyPF.127450$QU2.87340@fx01.iad> |
| In reply to | #70935 |
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.
Why not, it's actually not difficult.
Below is a simple example (actually returns true for big endian) but I think
more complex checks can be built upon same principle.
#include <cstdint>
#include <iostream>
using namespace std;
enum ProbeEnum : int16_t { ProbeValue = 0x0100 };
constexpr union {
ProbeEnum p;
char ca[2];
} ProbeVal{ProbeValue};
constexpr
bool
IsBigEndian()
{
return !!ProbeVal.ca[0];
}
int
main(int, char*[])
{
cout << "IsBigEndian=" << IsBigEndian() << endl;
return 0;
}
HTH
-Pavel
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2020-01-02 19:51 -0800 |
| Message-ID | <chine.bleu-1058BC.19512102012020@reader.eternal-september.org> |
| In reply to | #70992 |
In article <1yyPF.127450$QU2.87340@fx01.iad>, Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> wrote: > Below is a simple example (actually returns true for big endian) but I think > more complex checks can be built upon same principle. Four bytes let's you detect Dec's middle endian. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ The first law of discordiamism: The more energy This post / \ to make order is nore energy made into entropy. insults Islam. Mohammed
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2020-01-02 23:14 -0800 |
| Message-ID | <480ef1d4-c8fa-4d08-bc06-35f7199446a2@googlegroups.com> |
| In reply to | #70992 |
On Friday, 3 January 2020 05:29:08 UTC+2, Pavel wrote:
> 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.
> Why not, it's actually not difficult.
>
> Below is a simple example (actually returns true for big endian) but I think
> more complex checks can be built upon same principle.
>
> #include <cstdint>
> #include <iostream>
> using namespace std;
>
> enum ProbeEnum : int16_t { ProbeValue = 0x0100 };
> constexpr union {
> ProbeEnum p;
> char ca[2];
> } ProbeVal{ProbeValue};
>
> constexpr
> bool
> IsBigEndian()
> {
> return !!ProbeVal.ca[0];
> }
>
> int
> main(int, char*[])
> {
> cout << "IsBigEndian=" << IsBigEndian() << endl;
>
>
> return 0;
> }
In C++ type punning through union is undefined behavior. Type punning
through reinterpret cast to pointer of bytes and type punning through
memcpy are valid but are not constexpr in C++. So I feel that your code
has undefined behavior.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-03 08:31 +0100 |
| Message-ID | <qumqk4$okt$1@news.albasani.net> |
| In reply to | #70992 |
>> 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.
> Why not, it's actually not difficult.
> Below is a simple example (actually returns true for big endian)
> but I think more complex checks can be built upon same principle.
> #include <cstdint>
> #include <iostream>
> using namespace std;
> enum ProbeEnum : int16_t { ProbeValue = 0x0100 };
> constexpr union {
> ProbeEnum p;
> char ca[2];
> } ProbeVal{ProbeValue};
> constexpr
> bool
> IsBigEndian()
> {
> return !!ProbeVal.ca[0];
> }
> int
> main(int, char*[])
> {
> cout << "IsBigEndian=" << IsBigEndian() << endl;
>
>
> return 0;
> }
IsBigEndian isn't guaranteed compile-time evaluated.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-03 08:43 +0100 |
| Message-ID | <qumrb1$n08$1@news.albasani.net> |
| In reply to | #71001 |
Am 03.01.2020 um 08:31 schrieb Bonita Montero:
>>> 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.
>> Why not, it's actually not difficult.
>
>> Below is a simple example (actually returns true for big endian)
>> but I think more complex checks can be built upon same principle.
>> #include <cstdint>
>> #include <iostream>
>> using namespace std;
>> enum ProbeEnum : int16_t { ProbeValue = 0x0100 };
>> constexpr union {
>> ProbeEnum p;
>> char ca[2];
>> } ProbeVal{ProbeValue};
>> constexpr
>> bool
>> IsBigEndian()
>> {
>> return !!ProbeVal.ca[0];
>> }
>> int
>> main(int, char*[])
>> {
>> cout << "IsBigEndian=" << IsBigEndian() << endl;
>>
>>
>> return 0;
>> }
>
> IsBigEndian isn't guaranteed compile-time evaluated.
if i do: "if constexpr( IsBigEndian() )" I'll get:
"error C2131: expression did not evaluate to a constant"
[toc] | [prev] | [next] | [standalone]
| From | Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo> |
|---|---|
| Date | 2020-01-05 00:51 -0500 |
| Message-ID | <0QeQF.95983$Cb2.42884@fx44.iad> |
| In reply to | #71002 |
Bonita Montero wrote:
> Am 03.01.2020 um 08:31 schrieb Bonita Montero:
>>>> 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.
>>> Why not, it's actually not difficult.
>>
>>> Below is a simple example (actually returns true for big endian)
>>> but I think more complex checks can be built upon same principle.
>>> #include <cstdint>
>>> #include <iostream>
>>> using namespace std;
>>> enum ProbeEnum : int16_t { ProbeValue = 0x0100 };
>>> constexpr union {
>>> ProbeEnum p;
>>> char ca[2];
>>> } ProbeVal{ProbeValue};
>>> constexpr
>>> bool
>>> IsBigEndian()
>>> {
>>> return !!ProbeVal.ca[0];
>>> }
>>> int
>>> main(int, char*[])
>>> {
>>> cout << "IsBigEndian=" << IsBigEndian() << endl;
>>>
>>>
>>> return 0;
>>> }
>>
>> IsBigEndian isn't guaranteed compile-time evaluated.
>
> if i do: "if constexpr( IsBigEndian() )" I'll get:
> "error C2131: expression did not evaluate to a constant"
Right. If I try to do
constexpr bool ibe = IsBigEndian();
I receive more explicit error message from gcc:
error: accessing ‘Endian::ca’ member instead of initialized ‘Endian::p’ member
in constant expression
So the Big Brother is watching.. Then the answer to your question is probably
"not possible until C++20". With C++20 you should be able to write a similar
code using bit_cast which is constexpr as mentioned by Bo Persson on another thread.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-05 07:43 +0100 |
| Message-ID | <qus0ir$2f2$1@news.albasani.net> |
| In reply to | #71137 |
> So the Big Brother is watching.. Then the answer to your question is > probably "not possible until C++20". With C++20 you should be able to > write a similar code using bit_cast which is constexpr as mentioned by > Bo Persson on another thread. C++20 should not only provide an enum which tells if the machine is big or little endian. It should also provide wrapper-classes of all basic integral and floating-point datatypes in big as well as little endian with overloaded operators that swap the bytes if appropriate on reading and assignment. This could be f.e. done internally by the standard library's specific intrinsics for byte-swapping (f.e. with BSWAP for x86).
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-05 08:31 +0100 |
| Message-ID | <qus3c3$vlc$1@news.albasani.net> |
| In reply to | #71138 |
>> So the Big Brother is watching.. Then the answer to your question is
>> probably "not possible until C++20". With C++20 you should be able to
>> write a similar code using bit_cast which is constexpr as mentioned by
>> Bo Persson on another thread.
> C++20 should not only provide an enum which tells if the machine is big
> or little endian. It should also provide wrapper-classes of all basic
> integral and floating-point datatypes in big as well as little endian
> with overloaded operators that swap the bytes if appropriate on reading
> and assignment. This could be f.e. done internally by the standard
> library's specific intrinsics for byte-swapping (f.e. with BSWAP
> for x86).
So something like this:
#if defined(_MSC_VER)
#include <intrin.h>
#endif
#include <cstdint>
template<typename T>
struct big_endian
{
T operator =( T value );
operator T();
private:
big_endian();
};
template<>
struct big_endian<std::uint32_t>
{
big_endian() = default;
big_endian( std::uint32_t value );
std::uint32_t operator =( std::uint32_t value );
operator std::uint32_t();
private:
std::uint32_t swap( std::uint32_t value );
std::uint32_t m_value;
};
inline
big_endian<std::uint32_t>::big_endian( std::uint32_t value )
{
m_value = swap( value );
}
inline
std::uint32_t big_endian<std::uint32_t>::operator =( std::uint32_t value )
{
m_value = swap( value );
return value;
}
inline
big_endian<std::uint32_t>::operator std::uint32_t()
{
return swap( m_value );
}
inline
std::uint32_t big_endian<std::uint32_t>::swap( std::uint32_t value )
{
#if defined(_MSC_VER)
return _byteswap_ulong( value );
#elif defined(__GNUC__)
return __builtin_bswap32( value );
#else
std::uint32_t swapA = (value & 0x0000FFFFu) << 16,
swapB = (value & 0xFFFF0000u) >> 16;
return (swapA & 0x00FF00FFu) << 8 | (swapA & 0xFF00FF00u) >> 8;
#endif
}
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-05 08:34 +0100 |
| Message-ID | <qus3hp$q23$1@news.albasani.net> |
| In reply to | #71139 |
> std::uint32_t swapA = (value & 0x0000FFFFu) << 16, > swapB = (value & 0xFFFF0000u) >> 16; > return (swapA & 0x00FF00FFu) << 8 | (swapA & 0xFF00FF00u) >> 8; Forget it, doesn't work, but care about the principle.
[toc] | [prev] | [next] | [standalone]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2020-01-05 08:38 +0100 |
| Message-ID | <qus3pf$qh8$1@news.albasani.net> |
| In reply to | #71139 |
> std::uint32_t swapA = (value & 0x0000FFFFu) << 16,
> swapB = (value & 0xFFFF0000u) >> 16;
> return (swapA & 0x00FF00FFu) << 8 | (swapA & 0xFF00FF00u) >> 8;
This is correct:
std::uint32_t swapA = (value & 0x0000FFFFu) << 16 | (value &
0xFFFF0000u) >> 16;
return (swapA & 0x00FF00FFu) << 8 | (swapB & 0xFF00FF00u) >> 8;
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web