C++ etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
C++ etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

29 Ocak 2016 Cuma

C Veri Tipleri

stdint.h İle Gelen Tipler
C++ ile bu dosya içindeki tipler için specifier'lar sıraya bakılmaksızın kullanılabilir.
3 When multiple simple-type-specifiers are allowed, they can be freely intermixed with other decl-specifiers in any order.
Yani şu tanım doğrudur. long long tipi araya serpiştirilerek tanımlanıyor.
constexpr long static long const int signed x = 10;
C dilinde ise qualifier birden fazla tanımlansa bile sorun olmuyor.
5 If the same qualifier appears more than once in the same specifier-qualifier-list, either directly or via one or more typedefs, the behavior is the same as if it appeared only once....
Yani şu tanım doğrudur. İki defa const yazsak bile sorun olmuyor.
const long const long static const int const signed x = 10;

Sabit Büyüklükte Veri Tipleri
Okumayı kolaylaştırmak için, yazıya önce hep aynı büyüklükte olduğu garanti edilen veri tipleri ile başlamak istedim. Bu tipler stdint.h dosyasında tanımlı. Bu veri tipleri signed olanlar için intN_t unsigned olanlar içinse uintN_t şeklinde tanımlanıyor.

int8_t : genellikle typedef  const signed char int8_t olarak tanımlanır. Bir byte büyüklüğündedir
int16_t:
int32_t:
int64_t : 8 byte büyüklüğündedir. printf yapmak için aşağdaki gibi yapmak gerekir.

Büyüklüğü en az belli bit olması garanti edilen tipler
stdint.h dosyasında int_leastN_t şeklinde tanımlanıyorlar. Örneğin int_least8_t gibi. Bu veri tiplerinin kullanıldığı hiç bir yer görmedim ancak şöyle bir örnek verilebilir. Nadir görülen unsigned int'in 20 bit olduğu bir mimarimiz olsun. Bu mimaride

uint8_t : tanımsızdır.
uint_least8_t : 10 bit'lik char ile aynıdır
uint_fast8_t : muhtemelen unsigned int ile aynıdır.

Eğer bu tür egzotik mimariler ile çalışıyorsak uint_least8_t kullanılabilir.

Büyüklüğü en az belli bit olması garanti edilen tipler. Derleyici en hızlı olanını seçer
stdint.h dosyasında int_fastN_t şeklinde tanımlanıyorlar. Örneğin int_fast8_t gibi. Derleyici en az 8 bitlik bir değer seçer. Eğer 16 bit daha hızlı çalışacaksa 16 bitlik bir değer seçer. (an integral type, which is computed quickly, of at least 8 bits, but it could be 16 bits if they run faster, etc...) Bu veri tiplerinin kullanıldığı hiç bir yer görmedim.

int "most efficient" tiptir. int_fastN_t ise "most efficient type in speed"tiptir.

(7.20.1.3p2) "The typedef name int_fastN_t designates the fastest signed integer type with a width of at least N. The typedef name uint_fastN_t designates the fastest unsigned integer type with a width of at least N."

Dil İle Gelen Tipler

Değişken Büyüklükte Veri Tipleri
C ile gelen veri tipleri platform ve derleyiciye göre değişebiliyor.

Data Type Ranges(C++) sayfasında bazı örnekler var. Ayrıca C Data Types sayfası da faydalı.
Tablo

Type          | Storage size |  Value range
____________________________________________________________
char          | 1 byte       |  -128 to 127 or 0 to 255
unsigned char | 1 byte       |  0 to 255
signed char   | 1 byte       |  -128 to 127
int           | 2 or 4 bytes |  -32,768 to 32,767 or -2,147,483,648 to 2,147,483,647
unsigned int  | 2 or 4 bytes |  0 to 65,535 or 0 to 4,294,967,295
short         | 2 bytes      |  -32,768 to 32,767
unsigned short| 2 bytes      |  0 to 65,535
long          | 4 bytes      |  -2,147,483,648 to 2,147,483,647
unsigned long | 4 bytes      |  0 to 4,294,967,295
Benim anladığım C veri tipleri şu şekilde sınıflandırılabilir:

char başlığı altına düşenler
Bir byte olması gerekiyor. Şu cümle C++ standardından alıntı
sizeof(char), sizeof(signed char) and  sizeof(unsigned char) are 1.
int8_t veya uint8_t aynı şeyler. En büyük ve en küçük değerleri SCHAR_MIN ve SCHAR_MAX macroları ile almak mümkün. SCHAR_MIN -128 SCHAR_MAX ise 127'dir.

Boolean aslında bir bit olması gerektiği halde, işlemci register'ları 1 bit ile çalışmadığı için genellikle bir byte'lık bir veri tipi ile tanımlanır.

short başlığı altına düşenler
short  : en az 2 byte olması gerekiyor, genellikle de zaten 2 byte oluyorlar.

int başlığı altına düşenler
int (unsigned int vs.) : en az 2 byte olması gerekiyor. Ancak genellikle 4 byte oluyorlar. En büyük ve en küçük değerleri INT_MIN ve INT_MAX macroları ile almak mümkün. Unsigned en büyük değeri ise UINT_MAX macrosu ile alabiliriz. Buradaki soruda bir işlemcinin 2 byte'lık int'lere sahip olmasına örnek var.

long başlığı altına düşenler
long (long int, unsigned long vs.) : en az 4 byte olması gerekiyor, genellikle de zaten 4 byte oluyorlar. En büyük ve en küçük değerleri LONG_MIN ve LONG_MAX macroları ile almak mümkün. Unsigned en büyük değeri ise ULONG_MAX macrosu ile alabiliriz.

Not : gcc 32 bit için long'u 4 byte, 64 bit içinse 8 byte olarak tanımlıyor, Windows'ta hep 4 byte uzunluğunda.

long long başlığı altına düşenler
long long (unsigned long long ) : en az 4 byte olması gerekiyor. Genellikle  8 byte oluyorlar.
En büyük ve en küçük değerleri LLONG_MIN ve LLONG_MAX macroları ile almak mümkün. Unsigned en büyük değeri ise ULLONG_MAX macrosu ile alabiliriz.

Sabitleri yazarken aşağıdaki gibi yazmak lazım.
1LL << 40

Eğer sistemde long long tanımlı değilse aşağıdaki gibi tanımlanabilir. upper kısmı en büyük unsigned long ile çarpılarak daha büyük bir sayı elde ediliyor.

typedef struct longlong
{ unsigned long lower; long upper; }
longlong;

#define ToDouble64(ll)    /* Convert to a double.  */    \
    ((ll).upper * 4294967296.0 + (ll).lower)

8 byte'lık veri tipleri eğer unsigned ise 0 ve 18,446,744,073,709,551,615 arasında değer alabiliyor.
8 byte'lık veri tipleri eğer signed ise −9,223,372,036,854,775,808 ve +9,223,372,036,854,775,807 arasında değer alabiliyor.

printf yapmak için %lld veya %llu seçeneğini kullanmak gerekir.

printf("%lld", (long long)now);

Open GL
Eğer OpenGL gibi bir kütüphane ile uğraşıyorsak bazı veri tiplerinin hep aynı büyüklükte olması için kendi veri tipini kullanmak lazım.

GLuint : Her zaman 4 byte


26 Ocak 2016 Salı

C Programlarının Hafıza Yerleşimi

Not : Konu ile ilgili olarak Segmentation Fault başlıklı yazıya bakabilirsiniz.

C Programlarının Hafıza Yerleşimi
Uygulama yüklendiğinde bellek bir çok sayfaya ayrılır . Şimdi sayfaların çeşitlerine bakalım.

Not : Assembly Kodu
Assembly yazarken de benzer sayfaları görebiliriz.
SECTION .data          ; Section containing initialised data
...
SECTION .bss           ; Section containing uninitialized data 
...
SECTION .text          ; Section containing code

Salt Okunur Sayfalar - Read Only Segment
Bu .init, .text, .rodata sayfaları salt okunur oluyorlar.

.Text Sayfalar
Bu alan programın çalıştırılabilir makine kodunun saklandığı alandır. Code Segment olarak ta anılır.

.RoData
Read Only Data anlamına gelir. Kodun içindeki const değişkenlerdir.
const char *foo = "foo";
const int bar = 234;
Bu tür değişkenlerin değeri değiştirilmeye kalkılırsa uygulama hata verir.

.rodata normalde ram'de olur. Gömülü ortamda flash bellekte olsun istersek şöyle yaparız.
__attribute__((section(".flash.rodata"))) ...

Okunup Yazılabilir Sayfalar - Read/Write Segment
bss - ilklendirilmemiş veri
bss block started by symbol anlamına gelir. İlk değeri atanmamış değişkenler burada saklanır.
"The BSS segment, also known as uninitialized data, is usually adjacent to the data segment. BSS segment contains all global variables and static variables that are initialized to zero or do not have explicit initialization in source code."
.data - ilklendirilmiş veri
İlk değer atanmış değişkenler burada saklanır.

"The data area contains global and static variables used by the program that are explicitly initialized with a non-zero (or non-NULL) value. "

2 Ocak 2016 Cumartesi

C'de Time API'leri

C Dili
C dilinde zaman (time) ile çalışmak maharet istiyor.
Aşağıda buradan aldığım C dilinde kullanılabilecek çağrıların birbiri ile olan ilişkisini gösteren güzel bir şekil var. Bu yazıda şekildeki metodları ve eksik kalan kısımlar için POSIX tarafından sağlanan yetenekleri incelemeye çalıştım.


Veri Yapıları
time_t 
std::time_t yazısına taşıdım.

struct time - broken time olarak ta bilinir
struct tm yazısına taşıdım.

time

time metodu hem Posix hem de Windows sistemlerde 1 Ocak 1970 (UTC) gece yarısından (00:00:00) beri geçen süreyi saniye çözünürlüğünde alabilmemizi sağlar. (C dili biraz eski olduğu için çözünürlük saniye seviyesinde kalmış, daha yeni dillerde çözünürlük saniyeden yüksek olabiliyor) Bu API tarafindan döndürülen time_t veri tipi C standardı tarafından sabitlenmemiştir ve bazı platformlarda 32 bit bazılarındaysa 64 bit olabilmektedir. Eğer metodu çağrısında hata varsa -1 döner

The time function returns the implementation’s best approximation to the current calendar time. The value (time_t)(-1) is returned if the calendar time is not available.
time() ile ilgili notlar
Gnu C kütüphanesi Unix için derlenirse time API'si gettimeofday metodunu çağırarak tv.sec alanının değerini döndürür.
Linux içinse bir kernel çağrısı yaparak ve aldığı değeri döndürür.

ctime ve asctime (sabit formatta string'e çevirme)
ctime ve asctime ürettikleri string'in sonuna yeni satır (eol) karakteri eklerler. Bu metodlar yerine strftime kullanılması daha iyi olur.

ctime
verilen time_t saniyesini yerel saat diliminde string'e çevirir. Bu metod yerine, varsa ctime_r kullanılmalı.

asctime
asctime() metodu yazısına taşıdım.

strftime - struct tm yapısını formatlı string'e çevirir
Bu metodu kullanabilmek için şu satır dahil edilir.
#include <time.h>
Kullanılabilecek çevirme seçenekleri burada. Her seçenek portable değil. Portable olmak için kullanılabilecek seçenekler şunlar


If you want your code to be portable, your format ("fmt")
argument should use only the conversion specifiers defined by
the ANSI C standard (C89, to play safe).  These are
"aAbBcdHIjmMpSUwWxXyYZ%".
Seçeneklerde küçük harfler kısaltılmış isimleri, büyükler ise uzun hallerini göstermek için kulllanılmış.
Aşağıda bazılarını açıklamaları var.

Çok kullanılan seçenekler şöyle%b : Kısaltılmış ay ismi (Jun vs. g.b.)
%c : Seçili locale'e göre formatlama yapar. Çok kullanışlıdır.

%d : gün 
%m : ay
%Y : Yıl

%H : 24 saat cinsinden saat
%M : Dakika
%S: Saniye

Örneği buradan aldım.
char buff[20];
struct tm * timeinfo = localtime (&mtime);
strftime(buff, sizeof(buff), "%b %d %H:%M", timeinfo);
Şöyle kullanırız.
struct tm ts = ...;

char buffer[1024];

char format[512] = "%Y%m%d-%H%M%S";
strftime(buffer, sizeof(buffer), format, &ts); 
Çıktı olarak şunu alırız.
20151229-212305

strftime alternatifi
std::put_time kullanılabilir. Örnek:
#include <iostream>
#include <iomanip>
#include <ctime>

int main()
{
    auto t = std::time(nullptr);
    auto tm = *std::localtime(&t);
    std::cout << std::put_time(&tm, "%d-%m-%Y %H-%M-%S") << std::endl;
}

strptime -  formatlı string'i struct tm yapısına çevirir
strptime yazısına taşıdım.

gmtime ve localtime - saniyeden broken-down time'e çevirme

locattime
localtime ve gmtime yazısına taşıdım.

gmtime
localtime ve gmtime yazısına taşıdım.

mktime ve timegm ile ilgili notlar - broken-down time'dan saniyeye çevirme
mktime
std::mktime metodu yazısına taşıdım.

timegm
Bazı platformlarda - örneğin Linux gibi - timegm() tanımlı. Bu metod broken-down formattaki UTC saati  tekrar time_t veriyapısına döndürür. Eğer timegm metodu çalışılan platformda yoksa aşağıdaki gibi bir çözüm üretilebilir.

Bu metod içinde tzset() çağırılınca <time.h> içinde extern long timezone olarak tanımlanan değeri de atıyor. Bu değer bulunduğumuz saat dilimine göre UTC ile aramızdaki saniye farkını tutuyor. mktime metodu içinde saniye hesaplanırken timezone değeri de hesaba katılıyor(Satır 117)

24 Nisan 2015 Cuma

NonBuffered ve Buffered I/O

Bu yazı ile ilgili olarak Devpts başlıklı yazıyı okuyabilirsiniz.Orada da anlatıldığı gibi her process 3 tane posix stream ile başlatılıyor. Ancak bir çok programlama dili işletim sistemi tarafından atana bu posix streamlerin de üzerine başka soyutlamalar getiriyor. Bu yazıda bunlara kısaca bakacağız.

Not : I/O işlemlerinde eğer disk dolarsa ENOSPC hata kodu döndürülür.

Non-Buffered I/O

Non-Buffered I/O için işletim sistemi tarafından sağlanan open() metodu kullanılabilir Örnek :
open(filename, O_RDRW | O_CREAT, 0644);
open aslında 
int open(const char *pathname, int flags) ve
int open(const char *pathname,int flags, mode_t mode);
şeklinde iki imzaya sahip. 3 parametreli metod yani mode parametresi alan metod, flags alanında O_CREATE varsa dosyanın hangi haklarla yaratılacağını belirtmek için kullanılıyor. Yani özeti şu cümle.
mode specifies the permissions to use in case a new file is created.

Page Cache'in Kullanılmaması (Virtual Memory kullanılmaması)

Page Cache, the Affair Between Memory and Files başlıklı yazıda da anlatıldığı gibi non-buffered I/O yapsak bile işletim sistemi halen page cache yapısını kullanmaya devam etmekte. Bu sayfadaki page cache yapısını anlatan şekil aşağıda.



Eğer bu yapıyı da devre dışı bırakıp direkt diske yazmak istersek Linux üzerinde O_DIRECT seçeneği kullanılabilir. Bu durumda Page Cache kullanılmıyor ancak Disk Write Cache halen kullanılıyor.
Burada O_DIRECT açıklanmış.

 O_DIRECT'e karşılık olarak Windows'ta FILE_FLAG_NO_BUFFERING  (önbellekte tutma) seçeneği kullanılabilir.


Small file not committed to disk for over a minute sorusunda da açıklandığı gibi farklı dosya sistemleri farklı cache ayarları kullanabiliyorlar.


Bir dosyanın O_DIRECT seçeneği ile açılıp açılmadığını görmek için How to tell if a given process opened files with O_DIRECT? sorusunun cevabına göz atabilirsiniz. Bu bayrağın kullanılması diske yazma işleminde tüm verinin tamamen yazıldıktan sonra write() metodunun dönmesini garanti etmez! How are the O_SYNC and O_DIRECT flags in open(2) different/alike? sorusunda da bu durum açıklanıyor.

Verinin Diske Yazıldığını Garanti Etmek (Disk Write Cache kullanılmaması)
O_SYNC bayrağı ile verinin diske yazıldığını garanti etmek man sayfasına göre mümkün  çünkü man sayfasında şu cümle geçiyor. 
O_SYNC The file is opened for synchronous I/O. Any write(2)s on the resulting file descriptor will block the calling process until the data has been physically written to the underlying hardware.
Örnek : 
fd = open(filename, O_SYNC);
O_SYNC'e karşılık olarak Windows'ta FILE_FLAG_WRITE_THROUGH kullanılabilir. FILE_FLAG_WRITE_THROUGH seçeneğinin FILE_FLAG_NO_BUFFERING ile kullanılıp kullanılmaması aşağıda açıklanmış.

Ancak HDD, FS, O_SYNC : Throughput vs. Integrity yazısında da açıklandığı gibi HDD de kendi içinde bir önbellek kullanıyor. O_SYNC bayrağı kullanılsa bile bu verinin tamamen manyetik ortama yazıldığını garanti etmiyor.

POSIX guaranteeing write to disk sorusunda ise synch() metodunun kullanılması söylenmiş.

posix_fadvise metodu
Dosya açıldıktan sonra posix_fadvise metodu ile bir çok ince ayar daha yapmak mümkün. Örneğin 

POSIX_FADV_RANDOM :  Bu bayrak ile dosyaya rastgele bir şekilde erişileceğini belirtip işletim sistemi 
tarafından kullanılan read-ahead (önden okuma özelliği kapatılabilir).

POSIX_FADV_SEQUENTIAL : Bu bayrak ile dosyaya daha fazla read-ahead yapılması gerektiği belirtilir.
posix_fadvise(in_fd, 0, 0, POSIX_FADV_SEQUENTIAL);
POSIX_FADV_WILLNEED: İşletim sistemine read-ahead (önden okuma) işlemini ne kadar yapması söylenebilir. Örnek.
posix_fadvise(fd, 0, 512*1024*1024, POSIX_FADV_WILLNEED);
POSIX_FADV_DONTNEED: İşletim sistemine read-ahead için ayrılan bellek alanına ihtiyaç kalmadığı söylenir.

Büyük Dosyaları Okumak

Non-Buffered I/O ile Kullanılan Bazı Metodlar

close metodu
close metodu dosyayı kapatır. Burada anlatıldığı gibi bu metodun döndürdüğü değere mutlaka bakılması tavsiye ediliyor.
Eğer zaten kapatılmış olan bir dosyayı, tekrar kapatmaya kalkışırsak EBADF hatası alırız. Örnek:

fgets ve gets
gets() güvenli bir metod değil, bu yüzden mümkünse fgets() kullanılmalı.

Since the user cannot specify the length of the buffer passed to gets(), use of this function is discouraged. The length of the string read is unlimited. It is possible to overflow this buffer in such a way as to cause applications to fail, or possible system security violations.
fgets'in imzası şöyle
char * fgets ( char * str, int num, FILE * stream );
Metod şöyle kullanılır.

char name[256];
fgets(name,256,stdin);
Önemli bir nokta şu , gets newline karakterini de okunan string'e dahil eder!

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.
Bu karakterden kurtulmak için şöyle yapılabilir. Böylece \n karakteri yerine \0 koymuş oluruz.
while (fgets(buffer, sizeof buffer, stdin) != NULL) {
  size_t len = strlen(buffer);
  if (len > 0 && buffer[len - 1] == '\n')
    buffer[--len] = '\0';

  // use buffer
  printf("\"%s\"\n", buffer);
}
strlen yerine strcspn kullanılabilir. Veya strtok kullanılabilir. Her ne olursa olsun C ile dosya işlemleri ve string'ler yanyana gelmemesi gereken şeyler. İğrenç :)

ftruncate
Dosyayı verilen büyüklüğe getirir. Bu metod kullanılarak bir dosyanın başından ven sonundan bazı satırları silme örneği burada. ftruncate şu hataları dönebilir.
EROFS : File resides in a readonly file system.
EBADF : File is open for reading only
EINVAL : File descriptor refers to a file on which this operation is impossible.

Buffered I/O
C Dili
İşletim sistemi tarafından atanan 3 posix stream için C dilinde unistd.h dosyasında macrolar tanımlanmıştır. Bu macrolar aşağıdaki gibidir.

Ancak posix streamleri unbuffered I/O için tasarlanmışlardır. C dili ise buffered I/O yapmak için başka yapılar sunmaktadır. Bunlar yapılar stdio.h dosyasında tanımlıdır ve FILE yapılarıdır. Aşağıda bu durumu görebiliriz.



Yani C dilindeki stdin , stdout , stderr FILE struct'larıdır ve macrolardan farklı şeylerdir.

Burada bir konuya daha değinmek lazım. Nasıl olduğunu bilimiyorum ancak stderr stream'inin non-buffered olduğu yazıyor. Dolayısıyla stdout ve sterr aynı terminale yazdıklarında stdout çıktısı daha yazılmadan sterr çıktısını görebiliriz. Benzer sıkıntılar C# içinde geçerli.

Aşağıdaki şekli buradan aldım ve C dilinde buffered I/O yapıldığını daha iyi gösteriyor.
FILE struct'a Yazmak İçin
fprintf kullanılır. Burada dikkat edilmesi gereken nokta fprintf sadece FILE struct'a yazmaya yarar örneğin socket handle için kullanılamaz.

FILE Struct ile ilgili Diğer Metodlar
Listeyi buradan aldım.
fopen , fclose, freopen
fread, fwrite,
fflush,
fseek
fseek metodunu complexity'si burada tartışılmış.

fgetc,getc, getchar,
fputc, putc, putchar,
fputs

printf, fprintf, sprintf
scanf,fscanf,sscanf

fopen
Dosyayı sadece yazmak için açmak için "w" kullanmalıyız. Örnek:
FILE *file = fopen("/path","w")
freopen
freopen metodu yazısına taşıdım.

fputc
Tek bir karakter yazar.
fputc('1',file);
fputs
fputs sadece NULL ile biten string'i yazar. Eğer dosyaya NULL yazmak istiyorsak fwrite kullanmalıyız.

fscanf
scanf ailesinden olan bu metod ile dosyadan formatlı olarak veri okumak mümkün.


Buffer'ın Boyunu Değiştirmek
C Dili
I/O için kullanılan tampon'unun (buffer) boyunu değiştirmek için setbuf metodu kullanılır. Buffer yöntemini (unbuffered, line buffered, fully buffered) değiştirmek içinse  setvbuf metodu kullanılır.

setvbuf için örnek:
FILE* outf = //...
char obuffer[BUFSIZ];
//Full buffering: tampon tamamen dolunca yaz ve tamamen boşalınca oku
setvbuf(outf, obuffer, _IOFBF, sizeof(obuffer));
Buffer'ın boyunu seçerken BUFSIZ macrosu kullanılabilir. Bu macro her sistemde farklı bir değere sahip ve stream işlemleri için en uygun değeri taşıdığı yazılı.

NonBuffered I/O'dan Buffered I/O'ya Geçmek
C Dili
NonBuffered I/O'yu temsil eden bir stream fdopen() metodu ile buffered FILE* haline getirilebilir. Windows üzerinde ise _fdopen() kullanılır. Örnek:

int file;
FILE *stream = fdopen (file, "r");

Buffered I/O'dan NonBuffered I/O'ya Geçmek
C dili
Buffered I/O'yu temsil eden FILE* yapısı fileno (FILE* stream) metodu kullanılarak işletim sistemi tarafından kullanılan stream (file descriptor) numarasına çevirilebilir. Burada, gcc -std=gnu99 veya -D_POSIX_SOURCE seçenekleri ile derlenmesi gerektiği söylenmiş. Örnek:


Buffer'ı Boşaltmaya Zorlamak
C Dili
Bu iş için fflush() metodu kullanılıyor. Yanlız input için kullanılan bir stream üzerinde fflush kullanmak tanımsız bir davranış. Bu yüzden yapmamak lazım.

Buffer'ın Wide Oriented veya Byte Oriented Çalıştığını Kontrol Etmek
Sadece C dilinde  Byte-oriented veya Wide-oriented çalışma durumu var. Implementing perror() - issue sorusunda fwide kullanma örneği mevcut.
C++ Dili
std::cin , std::cout , std::cerr  C dilindeki yapılara karşılık geliyorlar. std::clog std::cerr ile aynı aycak std::cerr non-buffered iken std::clog buffered bir yapı.

C++ streamleri ile kullanılabilen özel karakterler var. 
\f : Ekranı temizlemek için kullanılabilir
\t : Bir tab karakteri koymak için kullanılabilir.

Java Dili
Java'da Flushable arayüzü ve bu arayüzü gerçekleştiren bir sürü sınıf var.

Bir diğer ilginç nokta ise Java ile gelen InputStream sınıfının non-buffered olmasına rağmen yine de available() diye bir metod sunması. Bu metod ile bloke olmadan okunabilecek byte sayısını almak mümkün