I'm not very happy with the do {} while() statement in C

Discussion of chess software programming and technical issues.

Moderators: hgm, Harvey Williamson, bob

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
Post Reply
lauriet
Posts: 162
Joined: Sun Nov 03, 2013 8:32 am
Contact:

Re: I'm not very happy with the do {} while() statement in C

Post by lauriet » Mon Mar 05, 2018 12:22 am

The "Pascal way" is to use boolean variables. I have never felt the need to use goto or break:

Done := False;
while not done
{
do stuff;
do stuff;
Done := Some test;
if not done then
{
do stuff;
do stuff;
}
}

AlvaroBegue
Posts: 919
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: I'm not very happy with the do {} while() statement in C

Post by AlvaroBegue » Mon Mar 05, 2018 1:03 am

Michael Sherwin wrote: Today I commented out the statements that set the globals to zero and it is as you said. However, I have a question. In my C primer which I admit was written more than 20 years ago it says that global variables should be initialized to zero or otherwise they may be undefined in some implementations of C. Is that so archaic that I should no longer take that into consideration or leave it in because it doesn't hurt. Or maybe leave them in but commented out just in case?
You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)

Also, C now (since C99) lets you declare variables anywhere, not just at the beginning of the function. You should get used to declaring the variable when it's first used. The resulting code is much easier to read.

Michael Sherwin
Posts: 3040
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: I'm not very happy with the do {} while() statement in C

Post by Michael Sherwin » Mon Mar 05, 2018 1:04 am

lauriet wrote:The "Pascal way" is to use boolean variables. I have never felt the need to use goto or break:

Done := False;
while not done
{
do stuff;
do stuff;
Done := Some test;
if not done then
{
do stuff;
do stuff;
}
}
This will also work and would be fine to do the extra testing since this is not time critical code. It just does not fit the style of C which strives to be as efficient as assembler, in theory that is. What I proposed with the process keyword block at the end of a do while loop is 100% the way I'd do it in assembly. But no one else likes my idea, lol. Oh well.
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

AlvaroBegue
Posts: 919
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: I'm not very happy with the do {} while() statement in C

Post by AlvaroBegue » Mon Mar 05, 2018 1:06 am

lauriet wrote:The "Pascal way" is to use boolean variables. I have never felt the need to use goto or break:

Done := False;
while not done
{
do stuff;
do stuff;
Done := Some test;
if not done then
{
do stuff;
do stuff;
}
}
I hate that style. Variables should contain data. Program flow should be controlled by language constructs that are designed for that purpose (like loops and goto).

Michael Sherwin
Posts: 3040
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: I'm not very happy with the do {} while() statement in C

Post by Michael Sherwin » Mon Mar 05, 2018 1:11 am

AlvaroBegue wrote:
Michael Sherwin wrote: Today I commented out the statements that set the globals to zero and it is as you said. However, I have a question. In my C primer which I admit was written more than 20 years ago it says that global variables should be initialized to zero or otherwise they may be undefined in some implementations of C. Is that so archaic that I should no longer take that into consideration or leave it in because it doesn't hurt. Or maybe leave them in but commented out just in case?
You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)

Also, C now (since C99) lets you declare variables anywhere, not just at the beginning of the function. You should get used to declaring the variable when it's first used. The resulting code is much easier to read.
More and more to learn all the time. Do you know that I am 60 years old and i never took a programming course. All I have is a twenty some year old C primer book. My newest question then is this. My global variables are used everywhere in the code. How can they be visible throughout the code if they are not global. The only way I can think of is to put the global variables in a structure and pass a pointer around. But that would be slower than just having global variables. What's the solution?
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

AlvaroBegue
Posts: 919
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: I'm not very happy with the do {} while() statement in C

Post by AlvaroBegue » Mon Mar 05, 2018 1:27 am

Michael Sherwin wrote:
AlvaroBegue wrote: You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)
[...] My global variables are used everywhere in the code. How can they be visible throughout the code if they are not global. The only way I can think of is to put the global variables in a structure and pass a pointer around. But that would be slower than just having global variables. What's the solution?
If you literally do what you describe, you won't improve the situation at all. The point of not using global variables is that each part of the code doesn't need to know about everything in the program, and by keeping the dependencies to a minimum your code is easier to understand, easier to check for correctness and easier to maintain.

If you give each part of the code access to only the parts that it needs, you will have to pass a few pointers around. A common way to do this is to organize your code into objects, and then most functions end up getting a first argument that is a pointer to the object on which it is being called (this is often called a "method"). When you set up the object (in a function called a "constructor"), you may have to pass pointers to a few other objects that this one needs access to, and you'll store them as part of this object, for later use.

It's a bit of a different mindset, and you don't have to be religious about it. But if you can identify parts of the code that naturally fall into this paradigm, use it. The more you use it, the more natural it will feel.

I have a confession to make: I have a bunch of global variables in my code. :) But they are far from being used all over the place, and I intend to clean it up. One thing that will push me in this direction is that I intend to parallelize my code, and threads don't mesh well with global variables.

Michael Sherwin
Posts: 3040
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: I'm not very happy with the do {} while() statement in C

Post by Michael Sherwin » Mon Mar 05, 2018 2:09 am

AlvaroBegue wrote:
Michael Sherwin wrote:
AlvaroBegue wrote: You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)
[...] My global variables are used everywhere in the code. How can they be visible throughout the code if they are not global. The only way I can think of is to put the global variables in a structure and pass a pointer around. But that would be slower than just having global variables. What's the solution?
If you literally do what you describe, you won't improve the situation at all. The point of not using global variables is that each part of the code doesn't need to know about everything in the program, and by keeping the dependencies to a minimum your code is easier to understand, easier to check for correctness and easier to maintain.

If you give each part of the code access to only the parts that it needs, you will have to pass a few pointers around. A common way to do this is to organize your code into objects, and then most functions end up getting a first argument that is a pointer to the object on which it is being called (this is often called a "method"). When you set up the object (in a function called a "constructor"), you may have to pass pointers to a few other objects that this one needs access to, and you'll store them as part of this object, for later use.

It's a bit of a different mindset, and you don't have to be religious about it. But if you can identify parts of the code that naturally fall into this paradigm, use it. The more you use it, the more natural it will feel.

I have a confession to make: I have a bunch of global variables in my code. :) But they are far from being used all over the place, and I intend to clean it up. One thing that will push me in this direction is that I intend to parallelize my code, and threads don't mesh well with global variables.
I don't mean to be a pain but to me it sounds like you are describing the C++ way. I know that C++ objects can be simulated in C using structures and being strict in using function calls accordingly. But then I might as well use C++. In my way of thinking C++ using objects is superior for a team project so team members do not trample all over another team members variable names and function names. For a single person working on a one file source C++ methodology does not seem (as) beneficial. I can write 32 bit assembler with the best of em. However, the nuances of 64 bit assembly is giving me a hard time or I'd be writing this primarily in assembler. My goal is writing code that is as fast as it can be. I have sort of a reputation for that or at least I did when RomiChess first came out and also my perft examples I wrote. My perft example in 32 bit assembler runs at 65 million nodes per second using a single thread on my 3.4GHz i7. Not bragging, just saying I like to stick with my programming style. And learning a new paradigm at my age is not easy. What you are suggesting that I should do by passing a pointer around I understand would not make a very noticeable difference in speed but learning a whole new paradigm at my age would certainly slow my progress. I thank you for the philosophical discussion and anything more that you would like to add. I wonder what others might think about what you are suggesting.

Bob? :D
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

pkumar
Posts: 93
Joined: Tue Oct 15, 2013 3:45 pm

Re: I'm not very happy with the do {} while() statement in C

Post by pkumar » Mon Mar 05, 2018 4:42 am

The more you use it, the more natural it will feel.

I have a confession to make: I have a bunch of global variables in my code. :)
I went through the pain of converting the code of "Nameless" to c++, the first line above is true. The process took less time than I anticipated.
Also, I have the same confession to make. :)

User avatar
lucasart
Posts: 3036
Joined: Mon May 31, 2010 11:29 am
Full name: lucasart
Contact:

Re: I'm not very happy with the do {} while() statement in C

Post by lucasart » Wed Mar 07, 2018 4:06 am

Michael Sherwin wrote:
AlvaroBegue wrote:
Michael Sherwin wrote:
AlvaroBegue wrote: You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)
[...] My global variables are used everywhere in the code. How can they be visible throughout the code if they are not global. The only way I can think of is to put the global variables in a structure and pass a pointer around. But that would be slower than just having global variables. What's the solution?
If you literally do what you describe, you won't improve the situation at all. The point of not using global variables is that each part of the code doesn't need to know about everything in the program, and by keeping the dependencies to a minimum your code is easier to understand, easier to check for correctness and easier to maintain.

If you give each part of the code access to only the parts that it needs, you will have to pass a few pointers around. A common way to do this is to organize your code into objects, and then most functions end up getting a first argument that is a pointer to the object on which it is being called (this is often called a "method"). When you set up the object (in a function called a "constructor"), you may have to pass pointers to a few other objects that this one needs access to, and you'll store them as part of this object, for later use.

It's a bit of a different mindset, and you don't have to be religious about it. But if you can identify parts of the code that naturally fall into this paradigm, use it. The more you use it, the more natural it will feel.

I have a confession to make: I have a bunch of global variables in my code. :) But they are far from being used all over the place, and I intend to clean it up. One thing that will push me in this direction is that I intend to parallelize my code, and threads don't mesh well with global variables.
I don't mean to be a pain but to me it sounds like you are describing the C++ way. I know that C++ objects can be simulated in C using structures and being strict in using function calls accordingly. But then I might as well use C++. In my way of thinking C++ using objects is superior for a team project so team members do not trample all over another team members variable names and function names. For a single person working on a one file source C++ methodology does not seem (as) beneficial. I can write 32 bit assembler with the best of em. However, the nuances of 64 bit assembly is giving me a hard time or I'd be writing this primarily in assembler. My goal is writing code that is as fast as it can be. I have sort of a reputation for that or at least I did when RomiChess first came out and also my perft examples I wrote. My perft example in 32 bit assembler runs at 65 million nodes per second using a single thread on my 3.4GHz i7. Not bragging, just saying I like to stick with my programming style. And learning a new paradigm at my age is not easy. What you are suggesting that I should do by passing a pointer around I understand would not make a very noticeable difference in speed but learning a whole new paradigm at my age would certainly slow my progress. I thank you for the philosophical discussion and anything more that you would like to add. I wonder what others might think about what you are suggesting.

Bob? :D
C++ vs. C; OOP vs. Procedural; Global vs. Local. These are different and unrelated things.

You can use C and write OOP. You can use C++ and use Procedural. You can use lots of globals or none, in C or C++.

Whatever you do, never be religious about it. Writing code that has 0 global variable for the sake of it is plain stupidity. Same as writing code without break, continue, goto, only 1 return per function, etc. Dogmatic rules are stupid.

Of course you need global variables. I don't know any engine that has zero global. At the very least you need things like the Hash Table to be global.

Just think of it this way: does this variable really need to be a global ? Imagine if it wasn't: how much would it complicate the code, carrying it through function parameters all over the place ? Of course using "struct" (or "class" which is exactly the same modulo C++ syntactic sugar) reduces the mess of adding function parameters, by structuring them into single arguments.

But, generally, good code is good code. Doesn't matter if it's C or C++ (or Python or Go or D or whatever you like). Doesn't matter if it's OOP or Procedural. You can write clean and well organized code in plain old C. For example: https://github.com/lucasart/demolito. You can also write incredibly bad code in C++, and there's no lack of that around. But that's not C++'s fault...
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.

Michael Sherwin
Posts: 3040
Joined: Fri May 26, 2006 1:00 am
Location: WY, USA
Full name: Michael Sherwin

Re: I'm not very happy with the do {} while() statement in C

Post by Michael Sherwin » Wed Mar 07, 2018 12:54 pm

lucasart wrote:
Michael Sherwin wrote:
AlvaroBegue wrote:
Michael Sherwin wrote:
AlvaroBegue wrote: You should not have global variables. That's the best way to not have to find out what the initialization rules are. :)
[...] My global variables are used everywhere in the code. How can they be visible throughout the code if they are not global. The only way I can think of is to put the global variables in a structure and pass a pointer around. But that would be slower than just having global variables. What's the solution?
If you literally do what you describe, you won't improve the situation at all. The point of not using global variables is that each part of the code doesn't need to know about everything in the program, and by keeping the dependencies to a minimum your code is easier to understand, easier to check for correctness and easier to maintain.

If you give each part of the code access to only the parts that it needs, you will have to pass a few pointers around. A common way to do this is to organize your code into objects, and then most functions end up getting a first argument that is a pointer to the object on which it is being called (this is often called a "method"). When you set up the object (in a function called a "constructor"), you may have to pass pointers to a few other objects that this one needs access to, and you'll store them as part of this object, for later use.

It's a bit of a different mindset, and you don't have to be religious about it. But if you can identify parts of the code that naturally fall into this paradigm, use it. The more you use it, the more natural it will feel.

I have a confession to make: I have a bunch of global variables in my code. :) But they are far from being used all over the place, and I intend to clean it up. One thing that will push me in this direction is that I intend to parallelize my code, and threads don't mesh well with global variables.
I don't mean to be a pain but to me it sounds like you are describing the C++ way. I know that C++ objects can be simulated in C using structures and being strict in using function calls accordingly. But then I might as well use C++. In my way of thinking C++ using objects is superior for a team project so team members do not trample all over another team members variable names and function names. For a single person working on a one file source C++ methodology does not seem (as) beneficial. I can write 32 bit assembler with the best of em. However, the nuances of 64 bit assembly is giving me a hard time or I'd be writing this primarily in assembler. My goal is writing code that is as fast as it can be. I have sort of a reputation for that or at least I did when RomiChess first came out and also my perft examples I wrote. My perft example in 32 bit assembler runs at 65 million nodes per second using a single thread on my 3.4GHz i7. Not bragging, just saying I like to stick with my programming style. And learning a new paradigm at my age is not easy. What you are suggesting that I should do by passing a pointer around I understand would not make a very noticeable difference in speed but learning a whole new paradigm at my age would certainly slow my progress. I thank you for the philosophical discussion and anything more that you would like to add. I wonder what others might think about what you are suggesting.

Bob? :D
C++ vs. C; OOP vs. Procedural; Global vs. Local. These are different and unrelated things.

You can use C and write OOP. You can use C++ and use Procedural. You can use lots of globals or none, in C or C++.

Whatever you do, never be religious about it. Writing code that has 0 global variable for the sake of it is plain stupidity. Same as writing code without break, continue, goto, only 1 return per function, etc. Dogmatic rules are stupid.

Of course you need global variables. I don't know any engine that has zero global. At the very least you need things like the Hash Table to be global.

Just think of it this way: does this variable really need to be a global ? Imagine if it wasn't: how much would it complicate the code, carrying it through function parameters all over the place ? Of course using "struct" (or "class" which is exactly the same modulo C++ syntactic sugar) reduces the mess of adding function parameters, by structuring them into single arguments.

But, generally, good code is good code. Doesn't matter if it's C or C++ (or Python or Go or D or whatever you like). Doesn't matter if it's OOP or Procedural. You can write clean and well organized code in plain old C. For example: https://github.com/lucasart/demolito. You can also write incredibly bad code in C++, and there's no lack of that around. But that's not C++'s fault...
In other words if one is good at what they do stick to it. And if one is not good at it then modify one's approach to get better. :!:
I hate if statements. Pawns demand if statements. Therefore I hate pawns.

Post Reply