17 Ocak 2020 Cuma

signal metodu

Giriş
Şu satırı dahil ederiz.
#include <signal.h>
İmzası şöyle.
typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);
Örnek
Şöyle yaparız.
void signal_handler(int signal_no);
int main() {
  signal(SIGINT, signal_handler);
  ...
  return 0;
}
void signal_handler(int signal_no) {
  if (signal_no == SIGINT){
  ...
  }
}
Örnek
Şöyle yaparız
#include <signal.h>

void signal_handler(int signum){
  ...
}

int main (void){

  signal (SIGALRM, signal_handler); 
  ...

}

16 Ocak 2020 Perşembe

std::common_type

Örnek
Açıklaması şöyle.
A function can have only one return type that has to be known at compile time. However, you can use std::common_type, to return a type that both parameters can be implicity converted to.
Şöyle yaparız.
#include <type_traits>
template <class X, class Y>
typename std::common_type<X,Y>::type big(X a, Y b)
{
  if (a > b)
    return a;
  else return b;
}
Kullanmak için şöyle yaparız.
int main() {
  auto x = big(4.2,42);
  std::cout << std::is_same<decltype(x),double>::value;
}

14 Ocak 2020 Salı

IEEE754 - Float

1. Assignment
Assignment işleminde range ve precision artışı olmaz. Açıklaması şöyle.
Except for assignment and cast (which remove all extra range and precision), the values of operations with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.
Örnek
Elimizde şöyle bir kod olsun. Eğer x NaN değilse y == x her zaman true sonuç döner.
float x = ...

float y = x;

assert(y == x)
3. Integer'a Cast
Örnek
Anladığım kadarıyla undefined behavior vermeyen sadece iki tane yöntem var. Şöyle yaparız. reinterpret_cast, static_cast gibi yöntemler doğru değil
[[nodiscard]] constexpr float int_to_float4(int x) noexcept
{
  return std::bit_cast<float>(x);
}

[[nodiscard]] float int_to_float5(int x) noexcept
{
  float destination;
  memcpy(&destination, &x, sizeof(x));
  return destination;
}
3. Cast
Örnek
Elimizde şöyle bir kod olsun.
long l=9223372036854775807L;
float f=static_cast<float>(l);
Bu işlem sonucunda elimize geçen float değerin ne olacağı std::fesetround() metodu ile atanan "rounding mode" ile belirleniyor. IEEE754 5 tane "rounding mode" tanımlıyor. Bunlar şöyle.
Rounding-direction attributes to nearest
1. roundTiesToEven
2. roundTiesToAway

Directed rounding attributes
1. roundTowardPositive
2. roundTowardNegative
3. roundTowardZero

4. Karşılaştırma
double ve float karşılaştırması doğru sonuç vermeyebilir.

Örnek
Şöyle yaparız ve sonuç olarak "no" alırız.
#include<iostream.h>
using namespace std;
int main()
{
  float x=1.1;
  if(x==1.1)
    cout<<"yes";
  else
    cout<<"no";
  return 0;
}

Order Of Evaluation

1. Metod Çağrısı
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);
Örnek
Bir 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ı olarak
line1
line2
yerine
line2
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 verelim
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.
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.
3.Aynı parametrenin birden fazla değer değiştirerek kullanılması
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.
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, and they are not potentially concurrent (1.10), the behavior is undefined.
Örnek - function call
Aynı parametreyi değiştirerek şöyle yapmamalıyız
msg[ipos++] = checksum(&msg[1], ipos-1);
Örnek - function call
Elimizde şö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ı şöyle
Thus, 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
Because increment and decrement operators have side effects, using expressions
with increment or decrement operators in a preprocessor macro can have undesirable results
Şöyle yapmamalıyız.
#define max(a,b) ((a)<(b))?(b):(a)
 k = max( ++i, j );