A note on strcpy

Code, algorithms, languages, construction...
User923005
Posts: 616
Joined: Thu May 19, 2011 1:35 am

Re: A note on strcpy

Post by User923005 » Thu Nov 28, 2013 2:31 am

Uninitialized variables are diagnosed by the compiler, if you have a decent one.
In a for loop, it is not undefined behavior to step one past the last element.
Of course, I have made programming errors. But I never do it intentionally.
If the manual says that something invokes undefined behavior, then I will not do whatever it says not to do.
The obvious exception is implementation defined behavior, or other cases where undefined behavior literally has to be invoked.

I do not know if there is a better solution to the problem.
Apple did not break working code. They broke broken code (code that relied on undefined behavior).
If you think that using undefined behavior is a fine thing to do in a program, then have at it.
I suppose that we will just have to differ here.

I do recognize your skill as a programmer. Crafty is clearly a strong chess playing engine and it shows the level of your ability.
I just think that it is always a big mistake to rely upon undefined behavior when there is a perfectly good alternative.

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: A note on strcpy

Post by hyatt » Thu Nov 28, 2013 2:59 am

User923005 wrote:Uninitialized variables are diagnosed by the compiler, if you have a decent one.
In a for loop, it is not undefined behavior to step one past the last element.
Of course, I have made programming errors. But I never do it intentionally.
If the manual says that something invokes undefined behavior, then I will not do whatever it says not to do.
The obvious exception is implementation defined behavior, or other cases where undefined behavior literally has to be invoked.

I do not know if there is a better solution to the problem.
Apple did not break working code. They broke broken code (code that relied on undefined behavior).
If you think that using undefined behavior is a fine thing to do in a program, then have at it.
I suppose that we will just have to differ here.

I do recognize your skill as a programmer. Crafty is clearly a strong chess playing engine and it shows the level of your ability.
I just think that it is always a big mistake to rely upon undefined behavior when there is a perfectly good alternative.

Sorry, most initialized variables are NOT caught by compilers. Only those that are local within a procedure. MANY get by because a compiler doesn't build a dependency graph for the entire code. It might not even SEE the entire code since most compile module by module. In fact, a compiler can't even deal with this:

int function(int init) {
int x;
if (init)
x=0;

x++;
}

Compiler has no way to determine what is passed into init. If it is anything but zero when it is called, all is well. Otherwise, it produces bogus values for x;

BTW, for the for loop, it is most certainly undefined. What if the last element of the array is at the end of a page of memory. You get a segfault. If it is not, you get garbage. What about going the other direction? Similar problems, and more since negative numbers can produce unexpected addresses. Bottom line, bugs happen. Using a right-to-left copy mechanism on overlapping strings doesn't fail if done correctly. It shouldn't, as Torvalds mentioned. Breaking code intentionally is not a good thing. It breaks easily enough due to other types of issues. My way of thinking is simply "let experienced programmers write code the way they want. If some can't deal with a sophisticated language, give them a "C for dummies" compiler that tries to be as intrusive as possible to prevent them from making mistakes. I write code in assembly language all the time, thankfully the assembler doesn't try to get in the way like this.

User923005
Posts: 616
Joined: Thu May 19, 2011 1:35 am

Re: A note on strcpy

Post by User923005 » Thu Nov 28, 2013 9:05 am

hyatt wrote:
User923005 wrote:Uninitialized variables are diagnosed by the compiler, if you have a decent one.
In a for loop, it is not undefined behavior to step one past the last element.
Of course, I have made programming errors. But I never do it intentionally.
If the manual says that something invokes undefined behavior, then I will not do whatever it says not to do.
The obvious exception is implementation defined behavior, or other cases where undefined behavior literally has to be invoked.

I do not know if there is a better solution to the problem.
Apple did not break working code. They broke broken code (code that relied on undefined behavior).
If you think that using undefined behavior is a fine thing to do in a program, then have at it.
I suppose that we will just have to differ here.

I do recognize your skill as a programmer. Crafty is clearly a strong chess playing engine and it shows the level of your ability.
I just think that it is always a big mistake to rely upon undefined behavior when there is a perfectly good alternative.

Sorry, most initialized variables are NOT caught by compilers. Only those that are local within a procedure. MANY get by because a compiler doesn't build a dependency graph for the entire code. It might not even SEE the entire code since most compile module by module. In fact, a compiler can't even deal with this:

int function(int init) {
int x;
if (init)
x=0;

x++;
}

Compiler has no way to determine what is passed into init. If it is anything but zero when it is called, all is well. Otherwise, it produces bogus values for x;

BTW, for the for loop, it is most certainly undefined. What if the last element of the array is at the end of a page of memory. You get a segfault. If it is not, you get garbage. What about going the other direction? Similar problems, and more since negative numbers can produce unexpected addresses. Bottom line, bugs happen. Using a right-to-left copy mechanism on overlapping strings doesn't fail if done correctly. It shouldn't, as Torvalds mentioned. Breaking code intentionally is not a good thing. It breaks easily enough due to other types of issues. My way of thinking is simply "let experienced programmers write code the way they want. If some can't deal with a sophisticated language, give them a "C for dummies" compiler that tries to be as intrusive as possible to prevent them from making mistakes. I write code in assembly language all the time, thankfully the assembler doesn't try to get in the way like this.

1>------ Rebuild All started: Project: dodo, Configuration: Debug Win32 ------
1> dodo.c
1>q:\dodo.c(6): warning C4716: 'function' : must return a value
1>q:\dodo.c(5): warning C4701: potentially uninitialized local variable 'x' used
1> main.c
1>q:\main.c(4): warning C4189: 'i' : local variable is initialized but not referenced
1> dodo.vcxproj -> q:\dodo\Debug\dodo.exe
dodo.c(5): warning : C6001: Using uninitialized memory 'x'.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
Attachments
main.c
(80 Bytes) Downloaded 232 times
dodo.c
(95 Bytes) Downloaded 219 times

User923005
Posts: 616
Joined: Thu May 19, 2011 1:35 am

Re: A note on strcpy

Post by User923005 » Thu Nov 28, 2013 9:13 am

Note that I do not claim that all forms of undefined behavior can be diagnosed by the compiler.
Only some obvious ones like the ones that I mentioned.
On the other hand, the programmer is responsible to know what is undefined behavior and avoid it if it is possible to avoid it.
I also do not claim that I have never invoked undefined behavior.
In fact, I have done a great deal of graphics programming in C. In order to do that it is necessary to invoke (at minimum) implementation defined behavior because the ANSI/ISO C standard says nothing about graphics.

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: A note on strcpy

Post by hyatt » Thu Nov 28, 2013 5:56 pm

User923005 wrote:
hyatt wrote:
User923005 wrote:Uninitialized variables are diagnosed by the compiler, if you have a decent one.
In a for loop, it is not undefined behavior to step one past the last element.
Of course, I have made programming errors. But I never do it intentionally.
If the manual says that something invokes undefined behavior, then I will not do whatever it says not to do.
The obvious exception is implementation defined behavior, or other cases where undefined behavior literally has to be invoked.

I do not know if there is a better solution to the problem.
Apple did not break working code. They broke broken code (code that relied on undefined behavior).
If you think that using undefined behavior is a fine thing to do in a program, then have at it.
I suppose that we will just have to differ here.

I do recognize your skill as a programmer. Crafty is clearly a strong chess playing engine and it shows the level of your ability.
I just think that it is always a big mistake to rely upon undefined behavior when there is a perfectly good alternative.

Sorry, most initialized variables are NOT caught by compilers. Only those that are local within a procedure. MANY get by because a compiler doesn't build a dependency graph for the entire code. It might not even SEE the entire code since most compile module by module. In fact, a compiler can't even deal with this:

int function(int init) {
int x;
if (init)
x=0;

x++;
}

Compiler has no way to determine what is passed into init. If it is anything but zero when it is called, all is well. Otherwise, it produces bogus values for x;

BTW, for the for loop, it is most certainly undefined. What if the last element of the array is at the end of a page of memory. You get a segfault. If it is not, you get garbage. What about going the other direction? Similar problems, and more since negative numbers can produce unexpected addresses. Bottom line, bugs happen. Using a right-to-left copy mechanism on overlapping strings doesn't fail if done correctly. It shouldn't, as Torvalds mentioned. Breaking code intentionally is not a good thing. It breaks easily enough due to other types of issues. My way of thinking is simply "let experienced programmers write code the way they want. If some can't deal with a sophisticated language, give them a "C for dummies" compiler that tries to be as intrusive as possible to prevent them from making mistakes. I write code in assembly language all the time, thankfully the assembler doesn't try to get in the way like this.

1>------ Rebuild All started: Project: dodo, Configuration: Debug Win32 ------
1> dodo.c
1>q:\dodo.c(6): warning C4716: 'function' : must return a value
1>q:\dodo.c(5): warning C4701: potentially uninitialized local variable 'x' used
1> main.c
1>q:\main.c(4): warning C4189: 'i' : local variable is initialized but not referenced
1> dodo.vcxproj -> q:\dodo\Debug\dodo.exe
dodo.c(5): warning : C6001: Using uninitialized memory 'x'.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

As I said. "potentially initialized variable" is most likely WRONG in that case. Many do this same thing with PRNGs. You see the warning enough, you ignore it, because it is mostly wrong.

BTW, what happens when you change that "0" to "1" in main.c? :)

Same thing? :)

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: A note on strcpy

Post by hyatt » Thu Nov 28, 2013 5:57 pm

User923005 wrote:Note that I do not claim that all forms of undefined behavior can be diagnosed by the compiler.
Only some obvious ones like the ones that I mentioned.
On the other hand, the programmer is responsible to know what is undefined behavior and avoid it if it is possible to avoid it.
I also do not claim that I have never invoked undefined behavior.
In fact, I have done a great deal of graphics programming in C. In order to do that it is necessary to invoke (at minimum) implementation defined behavior because the ANSI/ISO C standard says nothing about graphics.
I thought you would be fired for doing that?

User923005
Posts: 616
Joined: Thu May 19, 2011 1:35 am

Re: A note on strcpy

Post by User923005 » Thu Nov 28, 2013 9:57 pm

hyatt wrote:
User923005 wrote:
hyatt wrote:
User923005 wrote:Uninitialized variables are diagnosed by the compiler, if you have a decent one.
In a for loop, it is not undefined behavior to step one past the last element.
Of course, I have made programming errors. But I never do it intentionally.
If the manual says that something invokes undefined behavior, then I will not do whatever it says not to do.
The obvious exception is implementation defined behavior, or other cases where undefined behavior literally has to be invoked.

I do not know if there is a better solution to the problem.
Apple did not break working code. They broke broken code (code that relied on undefined behavior).
If you think that using undefined behavior is a fine thing to do in a program, then have at it.
I suppose that we will just have to differ here.

I do recognize your skill as a programmer. Crafty is clearly a strong chess playing engine and it shows the level of your ability.
I just think that it is always a big mistake to rely upon undefined behavior when there is a perfectly good alternative.
Sorry, most initialized variables are NOT caught by compilers. Only those that are local within a procedure. MANY get by because a compiler doesn't build a dependency graph for the entire code. It might not even SEE the entire code since most compile module by module. In fact, a compiler can't even deal with this:

int function(int init) {
int x;
if (init)
x=0;

x++;
}

Compiler has no way to determine what is passed into init. If it is anything but zero when it is called, all is well. Otherwise, it produces bogus values for x;

BTW, for the for loop, it is most certainly undefined. What if the last element of the array is at the end of a page of memory. You get a segfault. If it is not, you get garbage. What about going the other direction? Similar problems, and more since negative numbers can produce unexpected addresses. Bottom line, bugs happen. Using a right-to-left copy mechanism on overlapping strings doesn't fail if done correctly. It shouldn't, as Torvalds mentioned. Breaking code intentionally is not a good thing. It breaks easily enough due to other types of issues. My way of thinking is simply "let experienced programmers write code the way they want. If some can't deal with a sophisticated language, give them a "C for dummies" compiler that tries to be as intrusive as possible to prevent them from making mistakes. I write code in assembly language all the time, thankfully the assembler doesn't try to get in the way like this.

1>------ Rebuild All started: Project: dodo, Configuration: Debug Win32 ------
1> dodo.c
1>q:\dodo.c(6): warning C4716: 'function' : must return a value
1>q:\dodo.c(5): warning C4701: potentially uninitialized local variable 'x' used
1> main.c
1>q:\main.c(4): warning C4189: 'i' : local variable is initialized but not referenced
1> dodo.vcxproj -> q:\dodo\Debug\dodo.exe
dodo.c(5): warning : C6001: Using uninitialized memory 'x'.
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

As I said. "potentially initialized variable" is most likely WRONG in that case. Many do this same thing with PRNGs. You see the warning enough, you ignore it, because it is mostly wrong.

BTW, what happens when you change that "0" to "1" in main.c? :)

Same thing? :)
It is correctly diagnosed.
1>------ Build started: Project: dodo, Configuration: Debug Win32 ------
1> main.c
1>q:\main.c(4): warning C4189: 'i' : local variable is initialized but not referenced
1> dodo.c
1> Generating Code...
1>q:\dodo.c(5): warning C4701: potentially uninitialized local variable 'x' used
1> dodo.vcxproj -> q:\dodo\Debug\dodo.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: A note on strcpy

Post by hyatt » Fri Nov 29, 2013 3:51 am

Sorry, it is not "correctly identified." In my code, that function is ALWAYS called with a 1 argument before any other calls. Always initializes X. Compiler doesn't know that. Produces an incorrect message. Which was my point. The only thing worse than no diagnostic is an erroneous diagnostic. Because it lulls you to sleep when you have to ignore it. And then you will miss other real warnings...

User923005
Posts: 616
Joined: Thu May 19, 2011 1:35 am

Re: A note on strcpy

Post by User923005 » Fri Nov 29, 2013 4:00 am

hyatt wrote:Sorry, it is not "correctly identified." In my code, that function is ALWAYS called with a 1 argument before any other calls. Always initializes X. Compiler doesn't know that. Produces an incorrect message. Which was my point. The only thing worse than no diagnostic is an erroneous diagnostic. Because it lulls you to sleep when you have to ignore it. And then you will miss other real warnings...
You are mistaken.
The message "dodo.c(5): warning : C6001: Using uninitialized memory 'x'." is removed. In the previous case, initialized memory was definitely used and diagnosed.
However, the compiler cannot foresee all possible uses for the function (which could be called from a library or from another function tomorrow or who knows what). If the function is called with a zero parameter, the memory will be uninitialized.
Hence, we have the correct diagnosis: "potentially uninitialized local variable 'x' used" for the function.

In every case, it is up to the programmer to use his brain and examine the code when a warning message appears.
In this case, the programmer is correctly given a clear description of the function's bad construction.
In my view, the diagnostic is literally perfect.

You may feel free to defend your use of uninitialized behavior. The manual clearly told you not to do it. When you did it something went wrong. But the error was not with Apple. This is what we like to call "Pilot error."

hyatt
Posts: 1242
Joined: Thu Jun 10, 2010 2:13 am
Real Name: Bob Hyatt (Robert M. Hyatt)
Location: University of Alabama at Birmingham
Contact:

Re: A note on strcpy

Post by hyatt » Fri Nov 29, 2013 5:21 am

Is there a reason you keep changing the discussion? I have clearly stated, most of us compile chess engines as separate files. Using Make or something similar. The compiler will NOT "correctly" identify that x is or is not initialized, because it can't see the main procedure when compiling "dodo".

So let's stay on the same page. Or do you believe that a gigantic monolithic Linux kernel is built from one source file?

As I said, misleading diagnostics are worse then no diagnostics.

And for the record, this was not "pilot error". It was "manufacturer error".

Post Reply