Today, I showed a sample code about while statement to my students. But got a error result. :-[
I think it might be a bug related to optimization. Because when I close optimization, I can get the right value.
Pelles C v14, Windows 11 pro Chinese (Samplify) 25H2
1.png
Hi ander_cc,
A good lesson there similar to a lawyers credo "In Court don't ask a question if you don't already know the answer" the corollary to teaching, esp programing, is "In classroom don't use an example you haven't tested" :) (half kidding you, no offense meant)
But seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these. I have many programs using optimizations successfully.
Perhaps Pelle can find the cause of this short program, meanwhile
Your program can use optimizations by using this 'fix':
volatile int i=1;
which, as I understand it inhibits the optimizer from making assumptions about i.
John Z
As an aside I would recommend not using any optimizations for teaching. Optimizing should be performed by the students learning programing.
Cheers,
Compiling the code with the maximize speed option :
#include <stdio.h>
int main(void)
{
int i=1, sum=0;
while (i<=100)
{
//printf("i=%d\n",i);
sum=sum+i;
i++;
}
printf("i=%d\n",i);
printf("sum=%d\n",sum);
return 0;
}
Disassembling the object module :
_text SEGMENT PARA 'CODE' ; section number 1
main PROC
sub rsp, 40 ; 0000 _ 48: 83. EC, 28
lea rcx, [@152] ; 0004 _ 48: 8D. 0D, 00000000(rel)
call printf ; 000B _ E8, 00000000(rel)
lea rcx, [@154] ; 0010 _ 48: 8D. 0D, 00000000(rel)
mov edx, 5050 ; 0017 _ BA, 000013BA
call printf ; 001C _ E8, 00000000(rel)
xor eax, eax ; 0021 _ 31. C0
add rsp, 40 ; 0023 _ 48: 83. C4, 28
ret ; 0027 _ C3
main ENDP
_text ENDS
.xdata SEGMENT ALIGN(8) 'CONST' ; section number 3
..?xdatasym1 label byte
db 01H, 04H, 01H, 00H, 04H, 42H, 00H, 00H ; 0000 _ .....B..
.xdata ENDS
.rdata SEGMENT PARA 'CONST' ; section number 4
@154 label byte
db 73H, 75H, 6DH, 3DH, 25H, 64H, 0AH, 00H ; 0000 _ sum=%d..
@152 label byte
db 69H, 3DH, 25H, 64H, 0AH, 00H ; 0008 _ i=%d..
.rdata ENDS
The first printf call should take a second parameter, edx pointint the value of i. Since this statement is missing, printf will print the random value stored by the register edx.
For small tests quick look with podump.exe
Disasm obj Add-In (https://forum.pellesc.de/index.php?msg=26516)
Hi Timo,
Here is the output of Podump :
\PellesC\bin\podump.exe /DISASM output\sum.obj
sub rsp,28
lea rcx,[@152]
call printf
lea rcx,[@154]
mov edx,13BA
call printf
xor eax,eax
add rsp,28
ret
Quote from: John Z on April 14, 2026, 04:43:36 PMHi ander_cc,
A good lesson there similar to a lawyers credo "In Court don't ask a question if you don't already know the answer" the corollary to teaching, esp programing, is "In classroom don't use an example you haven't tested" :) (half kidding you, no offense meant)
But seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these. I have many programs using optimizations successfully.
Perhaps Pelle can find the cause of this short program, meanwhile
Your program can use optimizations by using this 'fix':
volatile int i=1;
which, as I understand it inhibits the optimizer from making assumptions about i.
John Z
As an aside I would recommend not using any optimizations for teaching. Optimizing should be performed by the students learning programing.
Cheers,
Yes, It really embarrassed me at that time. I realized I had forgotten to turn off the optimization. Then I explained the reason to my students, and turned off optimization to test the code again, and used gcc -o2 to test the code again.
from Clang
main:
00000000 4883EC28 sub rsp, 28h
00000004 488D0D00000000 lea rcx, [??_C@_05BKKKKIID@i?$DN?$CFd?6?$AA@]
0000000B BA65000000 mov edx, 65h
00000010 E800000000 call printf
00000015 488D0D00000000 lea rcx, [??_C@_07MJFEPNKA@sum?$DN?$CFd?6?$AA@]
0000001C BABA130000 mov edx, 13BAh
00000021 E800000000 call printf
00000026 31C0 xor eax, eax
00000028 4883C428 add rsp, 28h
0000002C C3 ret
As Vortex mentioned, this was missingmov edx, 65h
By the way, uncommenting the line below will output the correct result :
printf("i=%d\n",i);
#include <stdio.h>
int main(void)
{
int i=1, sum=0;
while (i<=100)
{
printf("i=%d\n",i);
sum=sum+i;
i++;
}
printf("i=%d\n",i);
printf("sum=%d\n",sum);
return 0;
}
For all bug hunters, use pope.exe to check obj-file, as it have internal disassembler.
Quote from: Vortex on April 15, 2026, 10:35:59 AMBy the way, uncommenting the line below will output the correct result :
Very typical in my experience for the optimization failures. Sometimes even just a 1 byte change can make it work, or make it fail.
John Z
The trick i=i-(-1); seems to solve the issue :
#include <stdio.h>
int main(void)
{
int i=1, sum=0;
while (i<=100)
{
sum=sum+i;
//i++;
i=i-(-1);
}
printf("i=%d\n",i);
printf("sum=%d\n",sum);
return 0;
}
It might be a cdecl problem, so 32-bit programs can use stdcall to avoid it.
Disassembling the 32-bit MS COFF object module, building the project as 32-bit console application :
_text SEGMENT PARA PUBLIC 'CODE'
_main PROC NEAR
push eax
push offset @152
call _printf
add esp, 8
push 5050
push offset @154
call _printf
add esp, 8
xor eax, eax
ret
_main ENDP
.rdata SEGMENT DWORD PUBLIC 'CONST'
@154 label byte
db 73H, 75H, 6DH, 3DH, 25H, 64H, 0AH, 00H ; 0000 _ sum=%d..
@152 label byte
db 69H, 3DH, 25H, 64H, 0AH, 00H ; 0008 _ i=%d..
.rdata ENDS
A sanity check is missing in the loop idiom optimizer: triangular numbers. This affects all targets. We'll see when I can fix this...
/* The triangular numbers are given by the following formula:
* Tn = 1 + 2 + 3 + .. + n = (n * (n + 1)) / 2
*/
Quote from: John Z on April 14, 2026, 04:43:36 PMBut seriously yes there have been, and are issues, with using the optimizations and extensive testing is always needed for these. I have many programs using optimizations successfully.
I my experience, enabling the optimizer on poorly written C code is more of a problem than the optimizer itself.
Hi Pelle,
This code below outputs the correct result. Tested with Pelles C v14 :
#include <stdio.h>
int main(void)
{
int i;
int s=0;
for (i=1;i<11;i++)
{
s=s+i;
}
printf("Sum = %d\n",s);
return 0;
}
Sum = 55
Optimizations : Maximize speed
Are you sure because adding the print of i to check shows maybe not-
If i becomes corrupt but it is not looked at - is it really corrupt ;D
Schrödinger's cat according to quantum theory, i is simultaneously good and bad until viewed
;)
#include <stdio.h>
int main(void)
{
int i;
int s=0;
for (i=1;i<11;i++)
{
s=s+i;
}
printf("i = %d\n",i);
printf("Sum = %d\n",s);
return 0;
}
This also appears to be OK as long as not looking at the value of i -
#include <stdio.h>
int main(void)
{
int i = 1;
int s = 0;
do {
s = s + i;
i++;
} while (i <= 10);
printf("i = %d\n", i);
printf("Sum = %d\n", s);
return 0;
}
using volatile int i has 'fixed' it every time...
John Z
Quote from: Pelle on April 18, 2026, 05:52:29 PMI my experience, enabling the optimizer on poorly written C code is more of a problem than the optimizer itself.
I agree with this also. In general I am seeing less and less issues as I program more...
John Z
I was too fast, same issue :
_text SEGMENT PARA 'CODE'
main PROC
sub rsp, 40
lea rcx, [@154]
call printf
lea rcx, [@156]
mov edx, 55
call printf
xor eax, eax
add rsp, 40
ret
main ENDP
_text ENDS
.rdata SEGMENT PARA 'CONST'
@156 label byte
db 53H, 75H, 6DH, 20H, 3DH, 20H, 25H, 64H ; 0000 _ Sum = %d
db 0AH, 00H
@154 label byte
db 69H, 20H, 3DH, 20H, 25H, 64H, 0AH, 00H ; 000A _ i = %d..
.rdata ENDS
Again, this line is fixing the issue :
for (i=1;i<11;i=i-(-1))
Many variations can complicate the use of i enough that the optimizer does not affect i.
Both of these variations within the loop also 'work' to inhibit the optimization -
s = s + (i*i)/i;
and
s = s + ((i << 1) >> 1);
We can probably find more too, but I'm fairly sure this is not helping -
#include <stdio.h>
int main(void)
{
int i = 1;
int s = 0;
do {
//s = s + (i*i)/i; // works
s = s + ((i << 1) >> 1); // works
i++;
} while (i <= 10);
printf("i = %d\n", i);
printf("Sum = %d\n", s);
return 0;
}
Another 'working' version
#include <stdio.h>
int main(void)
{
int i = 0;
int s = 0;
do {
++i;
s = s + i;
} while (i <= 9);
printf("i = %d\n", i);
printf("Sum = %d\n", s);
return 0;
}
John Z
Hi John Z, have a fun with Clang with limits with optimizations.
Optimizations for static code isn't so important and you know reasons for that.
The code below compiled as 32-bit application works fine :
#include <stdio.h>
int main(void)
{
int i;
int s=0;
for (i=1;i<11;)
{
s=s+i;
__asm inc i;
}
printf("i=%d , sum = %d\n",i,s);
return 0;
}
i=11 , sum = 55