Herkese merhaba arkadaşlar, dün C Programlama Dersine Giriş dersinin vizesine girdim ve vizede şuna benzer bir soru sordular.
#include <stdio.h>
int main()
{
int a = 10;
if(a == a++)
printf("True-1 ");
a = 10;
if(a == ++a)
printf ("True-2");
return 0;
}
Bu kodun çıktısı ne olur?
Ben, output’un
True-1
olduğunu düşündüm ama sınavdan sonra yanlış yaptığımı fark ettim.
Sınavdan sonra kodu şu şekilde derledim.
gcc -std=c99 -Wall -Werror a.c -o a
Ve uyarı verdi, derlemedi. Ama
gcc -std=c99 a.c -o a
Derleyince derledi.
Neyse işin hikayesini belki başkaları buna benzer bir sorun yaşarsa diye anlatmak istedim. Şimdi asıl konuya gelelim.
Yukarıdaki işlemleri yaptıktan sonra bunun Undefined Behaviour
olduğunu arkadaşlarla tespit ettik. Bir arkadaşım yukarıda bahsettiğim kodu mac de derleyince farklı, üniversitenin ssh ile bağlandığımız serverinde derleyince farklı bir çıktı verdi.
Bunun üzerine bunun nedenini araştırmaya başladım. Dün saat 21’den bugün saat 7’ye kadar bunun nedenini anlamaya çalıştım ve şöyle bir yazı kaleme aldım.
Ama bir konuyu hala tam anlayamadım. Seqpoint nedir? Biraz tanım biliyorum ama sanırım yeterli değil, yazdığım yazıyı okursanız seqpoint meselesini nasıl anladığımı anlayacaksınız. Ama seqpoint ile ilgili anlayamadığım birkaç şey var.
a[i] = i++
i = ++i
i++ * i++
gibi ifadeler UB(Undefined Behaviour) oluyor. Çünkü
seqpoint a[i] = i++ seqpoint
seqpoint i = ++i seqpoint
seqpoint i++ * i++
C standardını yanlış anlamadıysam şöyle diyor: iki seqpoint arasında bir değişkenin değeri en fazla bir kez değiştirilebilir.
Ama şu UB değil
int i = 0;
++i && i--
çünkü
seqpoint int i = 0; seqpoint
seqpoint ++i seqpoint i--
Yani && operatörünün olduğu yer seqpoint oluyor. Bu yüzden de her iki seqpoint arasında i değişkeni sadece bir kez modifiye ediliyor.
Şimdi asıl soruya gelmek istiyorum.
Eğer
i++ && i++
UB değil ama neden aşağıdaki ifade UB’dir?
#include <stdio.h>
void f(int x, int y)
{
printf ("%d %d\n", x, y);
}
int main()
{
int i = 0;
f(++i, ++i);
return;
}
Yani C standartlarında || && , ?:
operatörlerinin olduğu yer seqpoint ise neden
f(++i seqpoint ++i)
Şeklinde olmuyor veya oluyorsa neden UB veriyor.
Sorularımı toparlıyorum:
- Seqpoint tam olarak nedir?
- C standardındaki şu yazılar bize tam olarak ne demek istiyor, ne anlamamız gerekir? link
The Standard states that
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored.
- Standartta geçen tanımları kullanarak bir ifadenin UB olduğunu nasıl anlarız?
Yardımlarınız için şimdiden teşekkür ederim.