query: tag:C

assertが失敗した場合に任意のコードを実行してからabortを行うようにする方法の簡単な実装です。

c>>
#define ASSERT(cond)
for (; !(cond); assert(#cond == false))
<<--

  • レポートは素のassertに任せています
  • condを文字列化してcondが1度だけ評価されるようにします
  • falseとの比較でassertが失敗するようにし、レポートの見た目がそれっぽくなるようにします。

使用例:

c>>
ASSERT(a>0 && a%3 == 0){
printf("Invalid a: %d\n", a);
}
<<--

出力例:
pre>>
Invalid a: 1
Assertion failed: ("a>0 && a%3 == 0" == false), function fooBar, file baz.c, line 123
<<--

posted by genki genki on Sun 12 Dec 2010 at 19:43 with 0 comments

malloc(0)の戻り値は、NULLもしくはサイズが0のメモリ領域へのポインタのいずれかとなっています。どちらが帰ってくるかは処理系に依存するので、一見malloc(0)を使うとプログラムの移植性を損なうような気がします。

しかし、mallocで確保された領域を realloc や free で操作する場合、reallocもfreeもいずれも、サイズが0のメモリ領域へのポインタに対する操作とNULLポインタに対する操作を許容するので、実際には問題ありません。

posted by genki genki on Mon 23 Nov 2009 at 15:59 with 0 comments

gccで-std=c99を指定した時に、filenoが利用できなくて困ったのですが、
filenoはC標準ではなくて、POSIXの関数なので、以下のようなオプションを指定する必要があるようです。

pre>>
-D_POSIX_C_SOURCE=200112
<<--

See Also

posted by genki genki on Wed 20 May 2009 at 02:44 with 0 comments

C言語では、** #ifdef ** や ** #ifndef ** を使うことによって、条件付きのコンパイルが可能となる。

#ifdefの使い方と意味

#ifdefは、次のようにして使う。
c>>
#ifdef MACRO
 ・
 ・
 ・
#endif
<<c

これは、「MACROが定義されている場合は、#ifdef~#endifの中を有効にする」という意味である。

#ifndefの使い方と意味

次に、#ifndefは、逆の意味で、以下のように使う。
c>>
#ifndef MACRO
 ・
 ・
 ・
#endif
<<c

これは、「MACROが定義されていない場合は、#ifndef~#endifの中を有効にする」という意味である。

C言語でヘッダーを書くときの定石

この#ifndefを使ってヘッダーを書く、C言語の定石(?)がある。

以下のような、ヘッダーファイル my.h を定義する。
c>>
#ifndef MY_H /* ヘッダーの最初 /
#define MY_H
 ・
 ・
 ・
#endif /
ヘッダーの最後 */
<<c

こうすることによって、複数のソースから my.h がインクルードされていたとしても、** 確実に1度だけ ** my.h の中身を有効にすることができる。

これで、ヘッダーファイルの管理も楽になりますね!!

posted by y_tsuda y_tsuda on Fri 21 Nov 2008 at 10:41 with 0 comments

研究室で話してたら、驚かれた。

意外と知ってる人少ない??

コード
c>>
#include<stdio.h>

int main(int argc, char *argv[], char *env[])
{

printf("%d\n", printf("Hello, World.\n"));

return(0);

}
<<c

実行結果
io>>
$ ./printf_return
Hello, World.
14
<<io

ってことで、出力された文字列のバイト数が戻り値となります。

また、出力に失敗した場合は、負の値が入るとのことです。

posted by y_tsuda y_tsuda on Tue 21 Oct 2008 at 23:53 with 0 comments