揮発性のメモ2

http://d.hatena.ne.jp/iww/

C

Cで、breakが使えるスコープを使う

C

#define blockscope switch(0)default: puts("hoge\n"); puts("piyo\n"); blockscope{ puts("foo\n"); puts("bar\n"); if(baz==E_OK) break; puts("baz\n"); } puts("fuga\n"); 途中で小さいスコープを作ってbreakで脱出できるコードを書く方法で switch(0)d…

feofでループするとバグる

C PHP

feof() は終端まで到達していたらEOFを返すけど、終端かどうかは最後の文字の次の文字を読むまでわからない。 よって、while(!feof() みたいにループで1文字ずつ読むと、必ず最後にゴミがでる。今までファイルを1文字ずつ読んだことなんかなかったので、初め…

小数点以下の桁数を指定して表示する

123456 を 123456.00 みたいに小数点以下の桁数を指定して表示する var a = 123456; var n = 2; console.log( a.toFixed(n) ); // 123456.00 Number.prototype.toFixed() - JavaScript | MDN

呼び出しているライブラリと関数の一覧

nmでシンボルを抜き出して、フィルタをかけるMan page of nm nm -C hogehoge C C++ の関数名を可読にする nm コマンド – オブジェクトファイルのシンボル情報を表示する | Linuxコマンド.NET 呼び出してる関数⇒自分じゃ定義していない関数⇒未定義シンボル と…

AdLintで静的解析

C

結論から言うと、AdLintで静的解析してもあんまり意味なかった。 インストールも使い方もそこそこ簡単 出てくるメッセージも読みやすい mallocのfree忘れ、openのclose忘れなどは検知しない gccでWarningレベルガン上げにした方がずっと役立つ そもそも AdLi…

cygwinでgcc使うとき、無い関数とか

fdatasync fdatasync() は無いので、代わりに fsync() を使う。 Man page of FSYNC libiconv_open libiconv_open を使うときは libiconv-devel をインストールした上で、 -liconvオプションを付ける。 Win機に茶筅をインストール(3) Cygwin にChaSen を2つの…

printfと同じフォーマットの関数で同じ警告を出してもらう

C

gccの属性指定を使うと、printfをパクった関数でも同じような警告を出させるように宣言できる。 int log_printf( char *f, ... ) __attribute__ ((format (printf, 1, 2))); printfとtypedefの微妙な関係 - 無視されがち?なformt warning - 職業としてのプロ…

printfで%dはintにキャストされる

C

#include <stdio.h> int main(void) { unsigned int a=0x80000000; printf("sizeof(int)=%d\n",sizeof(int)); // 4 printf("d %d\n",a); // -2147483648 printf("ld %ld\n",a); // 2147483648 printf("u %u\n",a); // 2147483648 return 0; }</stdio.h>

Linuxのgccでは"linux"が定義されている

そんなん気づかないから1時間くらい悩んだ #ifdef linux #warning linuxは定義済み #endif typedef struct { char name[16]; int linux; } hoge_t; gpio_def.h:2:2: warning: #warning linuxは定義済み In file included from gpio_lib.h:5, from gpio_lib.c…

静的ライブラリをリンクする

C

直接ファイルをリンクする 一番楽なのは libhoge.a を直接指定してリンクする 静的ライブラリを後ろに書くのがコツ良い例 $ cc -lrt sample.o libhoge.a -o sample 悪い例 $ cc -lrt libhoge.a sample.o -o sample sample.o: In function `my_send': /home/u…

静的ライブラリを作る

C

all: libhoge.a libhoge.a: hoge1.o hoge2.o hoge3.o $(AR) $(ARFLAGS) $@ $^ 以下略静的ライブラリを作るにはアーカイバ ar を使う 変数ARのデフォルトは ar 変数ARFLAGSのデフォルトは rv Man page of ar

strncpy は文字列コピーじゃあない

C

Man page of STRCPY strncpyは文字列コピーと思ってはいけない。 名前にstrとかついてるだけのmemcpyの亜種、みたいに思わないとだめ。 void printbuf(int n){ int i; char buf[10]="@@@@@@@@@"; strncpy(buf,"hello",n); for(i=0;i<9;i++) printf("%02X ",b…

recvfromでバグを作りこむ

C

int result; char buf[256]; struct sockaddr_storage addr; socklen_t addrlen = 0; // ★バグ for(;;){ result = recvfrom(sd, buf, sizeof(buf), 0, &addr, &addrlen); if(result<0) continue; sendto(sd, "OK", 2, 0, &addr, addrlen); } recvfromで、ア…

後置インクリメントリターン

C

思った通りに動くので安心した #include <stdio.h> int inkuri() { static int a=0; return a++; } int main(void) { printf("a=%d\n", inkuri()); // 0 printf("a=%d\n", inkuri()); // 1 return 0; } 苦しんで覚えるC言語</stdio.h>

Makefile

C

書き換える分は最小になるよう、できるだけ自動で解決できるMakefileを目指す。 ソースやヘッダが増える分は自動で増える 最終生成物とオブジェクトの依存関係だけ書けば良いようにする # Makefile all:; #---- プロジェクトごとに書き換え ここから -------…

fopenして/procを読み書きする

fopenして値を取得して、+1して値を書き込む。 FILE *fp; int value; fp = fopen(procname, "a+"); fscanf(fp,"%d",&value); value++; fprintf(fp,"%d",value); fclose(fp); /procの下は仮想ファイルシステムなので、雑に"w+"とかでオープンしても壊れたりし…

可変引数の関数で、va_listは使いまわせない

C

標準出力とファイルと両方に書く関数を作ったとして、この書き方はNG int log_printf( FILE *fp, char *f, ... ) { va_list v; va_start( v, f ); vprintf( f, v ); // 標準出力 vfprintf( fp, f, v ); // ファイル出力 ★ va_end( v ); } これらの関数では v…

clock_gettime の使い方

C

Man page of CLOCK_GETRES #include <stdio.h> #include <time.h> char *getnow() { static char buf[32]; struct timespec t; struct tm tm; clock_gettime(CLOCK_REALTIME, &t); localtime_r(&t.tv_sec, &tm); strftime(buf, 32, "%Y-%m-%d %H:%M:%S.", &tm); sprintf(buf+2</time.h></stdio.h>…

構造体の大きさ

C

#include <stdio.h> typedef struct { char a; int b; char c; } hoge_t; int main(void) { printf("sizeof(hoge_t)=%d\n", sizeof(hoge_t)); return 0; } gcc version 4.9.2 32bit環境の場合 sizeof(hoge_t)=1264bit環境の場合 sizeof(hoge_t)=12てっきり64bit環境で</stdio.h>…

ビットフィールドの詰め方

C

gcc はビットフィールドが右詰め固定、LSBから順に使っていく #include <stdio.h> typedef union { unsigned int a; struct { unsigned int b1:4; unsigned int b2:4; unsigned int b3:4; unsigned int b4:4; unsigned int b5:4; unsigned int b6:4; unsigned int b7:</stdio.h>…

sscanf

C

int a; sscanf("100000000000000000000000000000000000000","%50d", &a); printf("%d\n",a);

配列の個数を数える

C

#include <stdio.h> int main(void) { char *h[] = {"aiueo","j","nu"}; int a = sizeof(h); int b = sizeof(h) / sizeof(char*); printf("%d\n",a); printf("%d\n",b); return 0; }</stdio.h>

make

C

$ make make: *** No rule to make target 'a.h', needed by 'main.o'. Stop.main.o をコンパイルするのに必要な a.h が見当たりません。

アトミックなメモリアクセスのための組込み関数 2

https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/_005f_005fatomic-Builtins.html jessieのコンパイラがgcc4.7.2だったのでやってみた アトミックなメモリアクセスのための組込み関数 - 揮発性のメモ #include <pthread.h> #include <stdio.h> volatile long long A=0; void *gett</stdio.h></pthread.h>…

signedとunsignedの比較

C

main(){ int a = -1; unsigned int b = 1; if(a>b){ printf("-1 is greater than 1\n"); } } 演算するときは unsigned側に引っ張られるのか。知らなかった。

ファイル名一覧取得

// printf用 #include <stdio.h> // opendir用 #include <sys/types.h> #include <dirent.h> // perror用 #include <stdlib.h> int main( int argc, char **argv ) { DIR *dir; struct dirent *dp; char *d_type; dir = opendir( argv[1] ); if( dir==NULL ){ perror("opendir"); exit(1); } while( (dp</stdlib.h></dirent.h></sys/types.h></stdio.h>…

if文の中のカンマ

C

int a=1; if( a==0, a==1 ) printf("Hello\n"); if文かどうかはあまり関係ない。 カンマ区切りは、左から順に実行(評価)してって、値としては一番右のを採用する。

fork

C

親が死んでも子は死なない #include <stdio.h> #include <unistd.h> void oya() { printf("OYA %d START\n", getpid()); sleep(5); *(char*)1 = 1; // ★ここで死ぬ printf("OYA END\n"); } void ko() { printf("KO %d START\n", getpid()); sleep(8); printf("KO END\n"); } int</unistd.h></stdio.h>…

getpeername()

C

ソケットからsockaddr構造体を引っ張ってくる関数 Man page of GETPEERNAME Man page of GETNAMEINFO #include <sys/socket.h> #include <netdb.h> #include <stdio.h> void print_peername( int sd ) { struct sockaddr_storage addr; // ソケットアドレス socklen_t addrlen; // ソケットア</stdio.h></netdb.h></sys/socket.h>…

writeとsprintf

C

result = write( fd, buf, sprintf(buf,"ABC=%5s\n",str) ); いいのかこのコード