1. Metod Çağrısı
Metoda geçilen parametrelerin hangi sırada işleneceğinin sırası belirsizdir.
Örnek
Şöyle yapmamalıyız.
Bir başka örnek
Şimdiye kadar verilen örneklerde metodu biz yazdık. Global +operator metodunda da aynı problem görülebilir. Örnek:
Örnek
Aynı problem << operatöründe de görülebilir.
2.Metod Interleaving
Örnek
Elimizde şöyle bir kod olsun.
1. new A
2. unique_ptr<A> constructor
3. new B
4. unique_ptr<B> constructor
C++17'ye kadar method interleaving olabiliyordu. Dolayısıyla önce 1, 3 , 2, ,4 çağrılabiliyordu. C++17 ile ya 1,2 ve 3,4 veya 3,4 ve 1,2 olabilir.
Örnek
Açıklaması şöyle.
Şöyle yapmamalıyız.
Aynı parametreyi değiştirerek şöyle yapmamalıyız
Elimizde şöyle bir kod olsun. Bu kod için order of evaluation belirsiz olduğu için unspecified davranışa sabep olur.
Şöyle yapmamalıyız. Iterator raw pointer döndürüyor olabilir.
Şöyle yapmamalıyız
Metoda geçilen parametrelerin hangi sırada işleneceğinin sırası belirsizdir.
C++ does not define the order in which function parameters are evaluated.Dolayısıyla metodun sonucu da tanımsızdır. Derleyiciden derleyiciye değişebilir.
Örnek
Şöyle yapmamalıyız.
f(i = 1, i = -1);
ÖrnekBir başka örnek
int nValue = Add(x, ++x);
ÖrnekŞimdiye kadar verilen örneklerde metodu biz yazdık. Global +operator metodunda da aynı problem görülebilir. Örnek:
std::cout << stream.readLine() + "\n" + stream.readLine() << std::endl;
Global + operatörü de parametreyi yani readLine() metodunu istediği sırada çağırabilir. Bu durumda çıktı olarakline1
line2
yerineline2
line1
alabiliriz.Örnek
Aynı problem << operatöründe de görülebilir.
int f() {
static int i = 0;
return i++;
}
int main() {
cout << f() << " " << f() << " " << f() << endl ;
return 0;
}
Çıktı olarak 2 1 0 alırız.2.Metod Interleaving
Örnek
Elimizde şöyle bir kod olsun.
void foo(std::unique_ptr<A>, std::unique_ptr<B> );
foo(std::unique_ptr<A>(new A), std::unique_ptr<B>(new B));
Bu çağrılara şöyle rakamlar verelim1. new A
2. unique_ptr<A> constructor
3. new B
4. unique_ptr<B> constructor
C++17'ye kadar method interleaving olabiliyordu. Dolayısıyla önce 1, 3 , 2, ,4 çağrılabiliyordu. C++17 ile ya 1,2 ve 3,4 veya 3,4 ve 1,2 olabilir.
Örnek
Açıklaması şöyle.
3.Aynı parametrenin birden fazla değer değiştirerek kullanılmasıcode such as f(std::shared_ptr<int>(new int(42)), g()) can cause a memory leak if g gets called after new int(42) and throws an exception, while f(std::make_shared<int>(42), g()) is safe, since two function calls are never interleaved.
The C++ language says you cannot modify a variable more than once between sequence pointsÖrnek - scalar
Şöyle yapmamalıyız.
a[i] = i++;
Açıklaması şöyle.Örnek - function callIf a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent (1.10), the behavior is undefined.
Aynı parametreyi değiştirerek şöyle yapmamalıyız
msg[ipos++] = checksum(&msg[1], ipos-1);
Örnek - function callElimizde şöyle bir kod olsun. Bu kod için order of evaluation belirsiz olduğu için unspecified davranışa sabep olur.
static int global_var = 0;
int update_three(int val)
{
global_var = val;
return 3;
}
main() {
int arr[5];
arr[global_var] = update_three(2);
}
Açıklaması şöyleThus, the C implementation may evaluate arr[global_var] first and then do the function call, in which case there is a sequence point between them because there is one before the function call, or it may evaluate global_var = val; in the function call and then arr[global_var], in which case there is a sequence point between them because there is one after the full expression. So the behavior is unspecified—either of those two things may be evaluated first—but it is not undefined.Örnek - iterator
Şöyle yapmamalıyız. Iterator raw pointer döndürüyor olabilir.
foo f;
auto it = f.begin();
*it = *it++; // <<== This is UB
Örnek - integralŞöyle yapmamalıyız
x = ++y + y++
Aslında standart tam olarak şunu söylüyor. Yani derleyici operand'ları istediği sırada çağırır, ve eğer bu çağrıların yan etkisi (side effect) varsa davranış tanımsızdır diyor.Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.
3.Macrolar
Açıklaması şöyle
Açıklaması şöyle
Because increment and decrement operators have side effects, using expressionsŞöyle yapmamalıyız.
with increment or decrement operators in a preprocessor macro can have undesirable results
#define max(a,b) ((a)<(b))?(b):(a)
k = max( ++i, j );
Hiç yorum yok:
Yorum Gönder