23 Kasım 2018 Cuma

std::is_const

Giriş
Açıklaması şöyle.
If T is a const-qualified type (that is, const, or const volatile), provides the member constant value equal true. For any other type, value is false.
İlginç bir şekilde reference tipler const kabul edilmiyorlar.

Örnek
Şöyle yaparız.
std::cout << std::is_const<int>::value << '\n'; // false
std::cout << std::is_const<const int>::value  << '\n'; // true
std::cout << std::is_const<const int*>::value  << '\n'; // false
std::cout << std::is_const<int* const>::value  << '\n'; // true
std::cout << std::is_const<const int&>::value  << '\n'; // false
Örnek
vector'ün döndürdüğü iterator int& veya const int& döner. Referans'ı kaldırmak için std::remove_reference() kullanılır. Şöyle yaparız
std::vector<int> vec{0};

for(auto it=vec.begin(); it!=vec.end(); ++it) {
  std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value;
}

for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
  std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value;
}
Örnek
Aşağıdaki örnekte l-value değişken const reference olarak perfert forwarding'e uğruyor ve const reference const kabul edilmediği için sonuç 0 çıkıyor.
#include <iostream> 
#include <type_traits> 
using namespace std; 
template<class T> 
void f(T&& t) 
{ 
     cout<<is_const<T>()<<endl; 
     //++t; 
} 
int main() { 
     const int i=0; 
     f(i); 
     return 0; 
} 

pragma once

Giriş
Include Guard yerine kullanılabilir. Normalde şöyle yaparız.
#ifndef MY_HEADER_HPP
#define MY_HEADER_HPP
...
#endif
pragma once bir çok derleyici tarafından destekleniyor ancak standart değil. Açıklaması şöyle.
There is no advantage to use of both the #include guard idiom and #pragma once in the same file.
Standart haline getirmek anladığım kadarıyla çok zor bir .
Örnek
Şöyle yaparız
#pragma once
...
...

22 Kasım 2018 Perşembe

__cplusplus macrosu

Macro Değeri
Açıklaması şöyle.
According to the standard, the __cplusplus macro must be defined, the exact definition depends on the C++ standard being used but it will not be zero.
Macronun değerini görmek için şöyle yaparız.
std::cout << __cplusplus << std::endl;
Şöyle yaparız.
std::cout << (unsigned int)__cplusplus << std::endl;
Çıktı olarak şunun gibi bir değer alırız.
201402
Ancak macro, her derleyici tarafından farklı bir anlam için kullanılmış. C++ derleyicisinin sürümünü anlamak için kullanıyorsak portable kod beklememek lazım. Örneğin Visual Studio 2012 macronun değerini halen 199711L olarak gösteriyor.

Eğer portable olmasını beklemeden C++ derleyicisinin sürümünü anlamak istersek şöyle yaparız.
#if __cplusplus > 201100L
#  define MYNULL nullptr
#else
#  define MYNULL NULL
#endif
Şöyle yaparız.
#if __cplusplus >= 201402L
[[deprecated]]
#endif
Örnek
Şöyle yaparız
#ifdef __cplusplus
extern "C" {...}
#endif
Örnek
Şöyle yaparız.
#if __cplusplus < 201103L
#error This source must be compiled as C++11 or later
#endif



std::out_of_range Exception Sınıfı

Giriş
Açıklaması şöyle.
There is no reference to the string used to initialise these exceptions when thrown by the standard library at all.
Açıklaması şöyle.
Exception text should never be shown to the user unless you created the text yourself. It will almost certainly not be anything other than English ASCII, but more to the point it won't be useful to users in 99% of cases. You should catch exceptions and show the user something actually useful, such as "Your name does not fit in our 1980's style database, so we have mutated it for you. Your name is now ${NAME}.

valgrind Invalid read Hatası

Giriş
Açıklaması şöyle.
An Invalid read means that the memory location that the process was trying to read is outside of the memory addresses that are available to the process. size 8 means that the process was trying to read 8 bytes. On 64-bit platforms this could be a pointer, but also for example a long int.

The last line of the error report says Address 0x38 is not stack'd, malloc'd or (recently) free'd, which means that the address that the process was trying to read 8 bytes from starts at 0x38. The line also says that the address is unavailable through stack space, heap space (malloc), or that it was recently a valid memory location.
by ile başlayan satırdan itibaren hatanın nerede oluştuğu takip edilebilir. at ile başlayan satır hatanın tam yerini belirtir.

Örnek
Şuna benzer bir çıktı alırız.
==6254== Invalid read of size 8
==6254==    at 0x4008C0: main (readin-test.c:26)
==6254==  Address 0x51fc2e0 is 0 bytes after a block of size 32 alloc'd
==6254==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6254==    by 0x400835: main (readin-test.c:16)
Örnek
Elimizde şöyle bir kod olsun.
FILE *file_pointer = fopen("humans.txt","r");

value = (char *) malloc(sizeof(char)); //burada 1 byte ayrılır


while( fscanf(file_pointer,"%s", value) != EOF ){
  printf("Name: %s Size of name: %d",value,strlen(value));
}
Çıktı olarak şunu alırız.
==22726== Invalid read of size 4
==22726==    at 0x4EA21BD: __isoc99_fscanf (in /usr/lib64/libc-2.17.so)
==22726==    by 0x400716: main (in /mnt//ogr/bxxxxx/a)
==22726==  Address 0x0 is not stack'd, malloc'd or (recently) free'd