Crafty c questions

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Crafty c questions

Post by mar »

bob wrote:(a) you have to cast to avoid warnings. That's the only purpose for the ones you mention. These were sent to me by someone that was trying to eliminate some warnings on their compiler. I have no idea why a recast would cause problems on C++. There's nothing wrong with

(void *) ((void * x)) other than redundancy
Well, AlignedMalloc is your own function and it expects void **, in C++ you can't implicitly cast void * to void **
(b) I am not aware of any memory leaks, which would cause the program to grow without constraint.
There's actually plenty of subtle leaks, to name a few,
where do you fclose prob_file in option.c in "Load" branch?
Where do you fclose craftyrc in AutoTune? etc.
Those all can be found easily with cppcheck (I'm sure other tools would work equally well).
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Crafty c questions

Post by mar »

Joost Buijs wrote:If you have 'pointer + x' you actually get the pointer + x * the size of the pointers object type and that is something completely different than 'pointer + sizeof(x)'.
Yes, absolutely. I'm actually surprised that the compiler accepts arithmetics on void ptrs :shock: Is it part of the C standard?!!
100% sure any C++ compiler would choke on that
Joost Buijs
Posts: 1564
Joined: Thu Jul 16, 2009 10:47 am
Location: Almere, The Netherlands

Re: Crafty c questions

Post by Joost Buijs »

mar wrote:
Joost Buijs wrote:If you have 'pointer + x' you actually get the pointer + x * the size of the pointers object type and that is something completely different than 'pointer + sizeof(x)'.
Yes, absolutely. I'm actually surprised that the compiler accepts arithmetics on void ptrs :shock: Is it part of the C standard?!!
100% sure any C++ compiler would choke on that
Most sources tell that arithmetic on void pointers in plain C is not allowed either. Bob's compiler (Intel C ?) seems to treat it like a byte pointer.
mvk
Posts: 589
Joined: Tue Jun 04, 2013 10:15 pm

Re: Crafty c questions

Post by mvk »

Implicit casting to and from void pointers is sane in standard C, and quite useful as it eliminates almost any need for ugly explicit pointer casts. It is not ok in C++ as I understand. (Personally I like C here better.)

Arithmetic on void pointers is a gcc extension and not valid in standard C.
[Account deleted]
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Crafty c questions

Post by bob »

Joost Buijs wrote:
bob wrote: If you have pointer + x, then the compiler will produce code that REALLY computes "pointer + sizeof(x)
If you have 'pointer + x' you actually get the pointer + x * the size of the pointers object type and that is something completely different than 'pointer + sizeof(x)'.

A void pointer cannot be dereferenced, it has no associated object size attached to it. Maybe it is the difference between C and C++, the code we are taking about will not be accepted by a C++ compiler.

Maybe this would work:

Code: Select all

memset((void *) ((char *)hash_table + node * mem_per_node), 0, mem_per_node);
You are right. I left out the multiply. Which is why the suggested parens will break rather than fix this...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Crafty c questions

Post by bob »

Joost Buijs wrote:
mar wrote:
Joost Buijs wrote:If you have 'pointer + x' you actually get the pointer + x * the size of the pointers object type and that is something completely different than 'pointer + sizeof(x)'.
Yes, absolutely. I'm actually surprised that the compiler accepts arithmetics on void ptrs :shock: Is it part of the C standard?!!
100% sure any C++ compiler would choke on that
Most sources tell that arithmetic on void pointers in plain C is not allowed either. Bob's compiler (Intel C ?) seems to treat it like a byte pointer.
No. Gcc 4.7 and 4.8, clang AND ICC.

All do it the same way.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: Crafty c questions

Post by bob »

mar wrote:
bob wrote:(a) you have to cast to avoid warnings. That's the only purpose for the ones you mention. These were sent to me by someone that was trying to eliminate some warnings on their compiler. I have no idea why a recast would cause problems on C++. There's nothing wrong with

(void *) ((void * x)) other than redundancy
Well, AlignedMalloc is your own function and it expects void **, in C++ you can't implicitly cast void * to void **
(b) I am not aware of any memory leaks, which would cause the program to grow without constraint.
There's actually plenty of subtle leaks, to name a few,
where do you fclose prob_file in option.c in "Load" branch?
Where do you fclose craftyrc in AutoTune? etc.
Those all can be found easily with cppcheck (I'm sure other tools would work equally well).
I don't have time to look at all, but the first one I looked at is autotune.c.

craftyrc is opened at the top, closed at the bottom...

fclose() is last line before final "}" character...

Will check the others later...
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Crafty c questions

Post by mar »

bob wrote: I don't have time to look at all, but the first one I looked at is autotune.c.

craftyrc is opened at the top, closed at the bottom...

fclose() is last line before final "}" character...

Will check the others later...
Right, but there's a return just below fopen. Such condition probably never happens though.
mar
Posts: 2559
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: Crafty c questions

Post by mar »

mvk wrote:Implicit casting to and from void pointers is sane in standard C, and quite useful as it eliminates almost any need for ugly explicit pointer casts. It is not ok in C++ as I understand. (Personally I like C here better.
Actually implicit casts to void * are fine in C++, so you can do things like

Code: Select all

char *c = ...;
void *f = c;
jwes
Posts: 778
Joined: Sat Jul 01, 2006 7:11 am

Re: Crafty c questions

Post by jwes »

bob wrote:
Joost Buijs wrote:
jwes wrote:I am trying to compile crafty 25.0 with MSVC 2013 and am running into some errors.

1. This line appears in init.c

Code: Select all

memset((void *) hash_table + node * mem_per_node, 0, mem_per_node);
This looks like a bug.
I guess you have to add some parentheses like:

Code: Select all

memset((void *) (hash_table + node * mem_per_node), 0, mem_per_node);
jwes wrote: 2. This function is used if INLINEASM is not defined and does not compile:

Code: Select all

int PopCnt(uint64_t arg1) {
  int c;

  for (c = 0; x; c++)
    x &= x - 1;
  return c;
}
You have to replace arg1 by x, then it will compile.
The parens will break the above.

If you have pointer + x, then the compiler will produce code that REALLY computes "pointer + sizeof(x)" That is not what is intended above. (void *) assumes the size of an object is 1, which makes this work correctly. The parens will produce seg faults because the pointers will go way out of bounds.
MSVC gives an error on (void *):
crafty-25.0\init.c(845): error C2036: 'void *' : unknown size