Some endian code for C++ programmers

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Some endian code for C++ programmers

Post by sje »

mcostalba wrote:
sje wrote:The very first bit of code in the application class constructor:

Code: Select all

  if (sizeof(si8)  != 1) Die("Bad sizeof(si8)  != 1");
  if (sizeof(ui8)  != 1) Die("Bad sizeof(ui8)  != 1");

  if (sizeof(si16) != 2) Die("Bad sizeof(si16) != 2");
  if (sizeof(ui16) != 2) Die("Bad sizeof(ui16) != 2");

  if (sizeof(si32) != 4) Die("Bad sizeof(si32) != 4");
  if (sizeof(ui32) != 4) Die("Bad sizeof(ui32) != 4");

  if (sizeof(si64) != 8) Die("Bad sizeof(si64) != 8");
  if (sizeof(ui64) != 8) Die("Bad sizeof(ui64) != 8");
Where I don't need to know integer sizes, I just use either "ui" or "si".
I would catch this at compile time with a static assert.

For some info look at

http://www.boost.org/doc/libs/1_38_0/do ... ssert.html

Altough you can build one yourself much more simple and without requiring including third part libraries.
Ah, but sometimes compile time assert semantics can be accidentally turned off. The above can't.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Some endian code for C++ programmers

Post by mcostalba »

sje wrote: Ah, but sometimes compile time assert semantics can be accidentally turned off. The above can't.
:?:
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Some endian code for C++ programmers

Post by sje »

mcostalba wrote:
sje wrote: Ah, but sometimes compile time assert semantics can be accidentally turned off. The above can't.
:?:
It's common practice in some places to use ASSERT instead of assert and select between debug and production modes via compiler command line preprocessor symbol definition. If the production version is accidentally selected, the assertion code won't not appear in the executable.
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Some endian code for C++ programmers

Post by mcostalba »

mathmoi wrote:Here is my solution with C++ templates.

I would have written:

Code: Select all

template<int From, int To>
struct Endian
{
  template<typename T>
  static inline T swap(const T& v) {return SwapBytes<T, sizeof(T)>(v);}
};

template<int FromTo>
struct Endian<FromTo, FromTo>
{
  template<typename T>
  static inline T swap(const T& v) {return v;}
};
and used like:

Code: Select all

int v = Endian<HOST_ENDIAN_ORDER, LITTLE_ENDIAN_ORDER>::swap(777);
int v2 = Endian<HOST_ENDIAN_ORDER, LITTLE_ENDIAN_ORDER>::swap(v);
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Some endian code for C++ programmers

Post by mcostalba »

sje wrote:
mcostalba wrote:
sje wrote: Ah, but sometimes compile time assert semantics can be accidentally turned off. The above can't.
:?:
It's common practice in some places to use ASSERT instead of assert and select between debug and production modes via compiler command line preprocessor symbol definition. If the production version is accidentally selected, the assertion code won't not appear in the executable.
executable?????

perhaps I am missing something, but here we are talking about compile time constraints. It it compiles is fine otherwise is broken.

With your code you are not checking the size of the machine where you run the program, but in the machine where you compile the program...am I missing something?


Just to be more clear, when you COMPILE this

Code: Select all

if (sizeof(si8)  != 1) Die("Bad sizeof(si8)  != 1"); 
compiler calculates sizeof(si8) and 1 as CONSTANTS and the above expression becomes:

Code: Select all

if (false) Die("Bad sizeof(si8)  != 1"); 
or, in the unlucky case;

Code: Select all

if (true) Die("Bad sizeof(si8)  != 1"); 
In any case the if() statement is completely optimized away in the executable...there is no more any fossil of it remaining when you RUN your code.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: Some endian code for C++ programmers

Post by sje »

What I'm saying is that some code is structured so that the compiler will wipe away all assets at compile time if a certain command line preprocessor symbol definition is given. My code covers that case as it is independent of any (mis-)selection of command line compilation options.
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Some endian code for C++ programmers

Post by Sven »

mcostalba wrote:Just to be more clear, when you COMPILE this

Code: Select all

if (sizeof(si8)  != 1) Die("Bad sizeof(si8)  != 1"); 
compiler calculates sizeof(si8) and 1 as CONSTANTS and the above expression becomes:

Code: Select all

if (false) Die("Bad sizeof(si8)  != 1"); 
or, in the unlucky case;

Code: Select all

if (true) Die("Bad sizeof(si8)  != 1"); 
In any case the if() statement is completely optimized away in the executable...there is no more any fossil of it remaining when you RUN your code.
The "if (false) Die(...)" may be optimized away completely (the "if" and the "Die"). That's o.k. since then the size is o.k. on the compile platform.

The "if(true) Die(...)" will at best be optimized to an unconditional "Die(...)" call. That's also o.k. since then you always want to get the error.

So I don't quite understand your remark, maybe I missed your point?

Sven
mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 9:17 pm

Re: Some endian code for C++ programmers

Post by mcostalba »

Sven Schüle wrote: So I don't quite understand your remark, maybe I missed your point?
My remark was that the above checking is a 100% compile time type checking so it would be better IMHO to use a static assert not (what it just seems) a run time check.

I didn't want to beat a dead horse but...if YOU write the static assert code then NO compiler option will ever remove YOUR code at least if you don't program your code to be removed if -g as example is not passed to gcc...but if you do this it means the boundary between runtime and compile time is blurry for you.

Also if you use a third party code like boost::static_assert, it will NOT be removed in release mode because simply has no sense. Run time asserts are removed to avoid overhead at runtime, but static asserts have ZERO overhead at runtime, they work only at compile time, so there is no need to disable the check when compiling in release mode.