A note for C programmers

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Henk
Posts: 7216
Joined: Mon May 27, 2013 10:31 am

Re: A note for C programmers

Post by Henk »

If you want to be sure that strcpy always copies from left to right better create a scrcpy2 yourself that does copy from left to right. You only need a global substitution to change strcpy in strcpy2.

The worst thing is to debug and find out that strcpy had been the cause of the bug.

I remember I had to implement an application in a so called TU(Lisp) language while they were changing the compiler/interpreter almost every day. They used me for testing their compiler. I did not like that at all.

By the way bugs in the garbage collector, I think, are the worst.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A note for C programmers

Post by Rein Halbersma »

bob wrote: I simply do not, and never will agree with the retarded concept that says "you can do anything if there is any possibility of undefined behavior."
And you won't have to, because the Standard does not require this from conforming implementations. Some forms of undefined behavior are too expensive to diagnose, and compilers do not have to solve e.g. the halting problem to decide whether they are in UB territory. In those cases, your program is likely to continue to run as if nothing was wrong. Only if it can prove that undefined WILL occur (not just possibly occur), does it obtain the freedom to do whatever it wants, including to run as it did for the last 25 years (which is precisely why you should avoid, because you can never be sure when the music stops).
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A note for C programmers

Post by Rein Halbersma »

bob wrote:
Rein Halbersma wrote:
Online example using gcc -O3 (gcc 4.6.4 on Linux)
So? 4.7.3 newer than 4.6.4... perhaps they realized such an optimization is a mistake.
Every online compiler I tried, gave the same thing:

http://rextester.com/runcode (running gcc 4.7.3) infinite loop, same warning
http://coliru.stacked-crooked.com/ (gcc 4.6.4 and g++ 4.8.1), both infinite loop, same warning, also on the same site with Clang 3.4 -03 prints 32 (didn't I tell you that anything could happen?).
http://gcc.godbolt.org/ all g++ versions 4.5 through 4.9 give an infinite loop
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: A note for C programmers

Post by syzygy »

bob wrote:
syzygy wrote:
bob wrote:
Rein Halbersma wrote:
bob wrote: So how about stopping with the hand waving and simply explain how to break a hash probe where I get an 8 byte signature that does not go with the corresponding 8 bytes of score and stuff. Then we can talk.
No, the burden of proof is on you. You claim that the compiler has no choice but to emit a sane set of instructions that give you the expected result. However, both the C11 and C++11 Standard leave no doubt that reads and writes from different threads to the same variable constitute undefined behavior.
I made no such claim. My claim is that the compiler is required to semantically do EXACTLY what I say.
Show me what in the C99 standard requires the compiler to let two different threads write into the same memory location.
Show me explicitly where it does not.
This question is too twisted to take seriously.
Show me specifically how it can even determine that that will happen in a place where it can then wreck the code.
You did not read what I wrote, or you did not understand.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A note for C programmers

Post by Rein Halbersma »

bob wrote:
Rein Halbersma wrote: There you go again. There is no "if one is careful" provision for UB. All bets are off once you go there. That's the part you have been wrong about for all this time, and too stubborn and proud to admit it.
Stick to repeating that over and over. Perhaps one day you can make it true. Meanwhile, integer overflow CAN be used. Race conditions CAN be dealt with. Some strcpy() overlap can be handled. etc...
The compiler CAN, but does not HAVE TO handle integer overflow or race conditions, it can do anything it pleases. And sometimes it will. In the case of integer overflows, almost every online compiler at -03 generates an infinite loop.
Rein Halbersma
Posts: 741
Joined: Tue May 22, 2007 11:13 am

Re: A note for C programmers

Post by Rein Halbersma »

syzygy wrote:
bob wrote:
Show me explicitly where it does not.
This question is too twisted to take seriously.
One is reminded of a Few Good Men: http://www.youtube.com/watch?v=fgIBG8q1Gjc In any case, let's give Colonel Jessup here the victory and let him return to his post . :roll:
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: A note for C programmers

Post by syzygy »

bob wrote:
syzygy wrote:
bob wrote:
syzygy wrote:
bob wrote:I don't care what the compiler does, it can't break the lockless hashing code. It is as simple as that. If you want to even try to convince me otherwise, here's the challenge:
You certainly do care what the compiler does.
a hash entry is 16 bytes. I have to write it as 2 8-byte blocks, each of which is certainly guaranteed to be atomic in x86 since that is what is written across the bus in one cycle.
Nope, the compiler is free to implement storing an uint64 as 8x storing a byte. Nothing in the standard stops the compiler from doing just that.

The compiler most likely won't do that, but here you are depending on the compiler and not on the C language.
And if you read what I wrote
Read what you wrote, I quoted it. "I have to write it as 2 8-byte blocks, each of which is certainly guaranteed to be atomic in x86[sic] since that is what is written across the bus in one cycle."
:)

How about the REST of that sentence you quoted:
I quoted all I needed. If you were not being precise, then that's your problem.

So what is it now. Are uint64 writes still guaranteed to be atomic by the C standard?

The important thing is this: the C standard does not in any way prescribe how a C compiler maps C source code to the machine. You can have a 64-bit processor, but there is no guarantee that 8-byte writes are atomic. And again, there is nothing in the C99 standard that prescibes that different threads see the same global variables. This is simple enough: the C99 standard is not even aware of threads.

Most compilers will have a sensible efficient mapping to the hardware, but if you rely on this you are completely dependent on the compiler. (Or on some other standard that the compiler implements, e.g. the phtread standard.)
syzygy
Posts: 5557
Joined: Tue Feb 28, 2012 11:56 pm

Re: A note for C programmers

Post by syzygy »

bob wrote:
Rein Halbersma wrote:
bob wrote:

Code: Select all

#include <stdio.h> 

int main&#40;) 
&#123; 
  int i, k = 0; 

  for &#40;i = 1; i > 0; i += i&#41; 
    k++; 
  printf&#40;"k = %d\n", k&#41;; 
  return 0; 
&#125;
Running gcc -O0 will produce 31 on architectures where an int is 32-bits. However, with gcc -O2 and higher, the compiler will recognize that "i += i" yields signed overflow UB. It will then eliminate the entire expression, and further optimize this code to an infinite loop. Such a scenario is also possible to happen with your XOR trick on multicore machines. Compiler routinely optimize away UB code instructions. You need extra compiler instructions or code modifcations to get the compiler to do what you intended.
Don't know what planet you compile on. Here's that run on my macbook:

scrappy% cc -O -o tst tst.c
.scrappy% ./tst
k = 31
scrappy% cc -O2 -o tst tst.c
scrappy% ./tst
k = 31
scrappy% cc -O3 -o tst tst.c
scrappy% ./tst
k = 31

gcc version 4.7.3 (MacPorts gcc47 4.7.3_3)
Online example using gcc -O3 (gcc 4.6.4 on Linux)
So? 4.7.3 newer than 4.6.4... perhaps they realized such an optimization is a mistake.
On my machine both 4.7.2 and 4.8.1 generate an infinite loop when compiling with -O3.
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: A note for C programmers

Post by bob »

Rein Halbersma wrote:
bob wrote: I simply do not, and never will agree with the retarded concept that says "you can do anything if there is any possibility of undefined behavior."
And you won't have to, because the Standard does not require this from conforming implementations. Some forms of undefined behavior are too expensive to diagnose, and compilers do not have to solve e.g. the halting problem to decide whether they are in UB territory. In those cases, your program is likely to continue to run as if nothing was wrong. Only if it can prove that undefined WILL occur (not just possibly occur), does it obtain the freedom to do whatever it wants, including to run as it did for the last 25 years (which is precisely why you should avoid, because you can never be sure when the music stops).
You have YET to describe what is going to happen with the undefined behavior of race conditions writing to memory. In fact, you can't even define a methodology to DETECT such race conditions. That would be the holy grail of any automatically parallelizing compiler, yet we don't have such. It has been proven to be impossible. C can't even tell when you break aliasing rules through a pointer, so you have to tell it either "I conform" or "I don't" so that it won't break your code. If it can't detect that, it has absolutely no chance of detecting those race conditions you are harping on that are undefined and which therefore ought to not be used or trusted...

This is a nonsensical discussion. In the extreme...
bob
Posts: 20943
Joined: Mon Feb 27, 2006 7:30 pm
Location: Birmingham, AL

Re: A note for C programmers

Post by bob »

Rein Halbersma wrote:
bob wrote:
Rein Halbersma wrote: There you go again. There is no "if one is careful" provision for UB. All bets are off once you go there. That's the part you have been wrong about for all this time, and too stubborn and proud to admit it.
Stick to repeating that over and over. Perhaps one day you can make it true. Meanwhile, integer overflow CAN be used. Race conditions CAN be dealt with. Some strcpy() overlap can be handled. etc...
The compiler CAN, but does not HAVE TO handle integer overflow or race conditions, it can do anything it pleases. And sometimes it will. In the case of integer overflows, almost every online compiler at -03 generates an infinite loop.
"almost every compiler" does not. I gave you several GCC versions that work perfectly, and was unable to find a single one on any machine we have that optimizes that far. The Intel C compiler (one version) broke it. Two other versions did not. The only other useful compiler around is mdvc. Have you tried it?

Please stop writing the nonsense about race conditions. The compiler can't even RECOGNIZE them, much less do anything with 'em. If you don't believe me, go find a good compiler guy and ask. Or look up some of the research done by (say) Ken Kennedy or Kuch and associates. Then you will understand why. If the compiler can't even detect the condition, what will/can it POSSIBLY do to break it? If I know what I am doing to deal with the race condition, it will work correctly, period.