int型のサイズが4でなかったらエラー

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

int型のサイズが4でなかったらエラー

#1

投稿記事 by みけCAT » 9年前

開発環境はDev-C++4.9.9.2日本語版、gccのバージョンは3.4.2です。
int型のサイズが4バイトではなかったらエラーにしたいと思い、次のコードを書きました。

コード:

#include <stdio.h>

#if sizeof(int)!=4
#error sizeof(int) must be 4
#endif

int main(void) {
	printf("Hello,World!\n");
	return 0;
}
このコードだと、次のエラーが出ます。
3:11 D:\(中略)\intsizemust4.c missing binary operator before token "("
どうすればうまくいくか教えてくれるとありがたいです。
よろしくお願いします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

maru

Re: int型のサイズが4でなかったらエラー

#2

投稿記事 by maru » 9年前

sizeofはプリプロセスでは処理されないからでしょうね。

コード:

#include "limits.h"
#if INT_MAX!=LONG_MAX
ではいかがでしょうか。

やんち

Re: int型のサイズが4でなかったらエラー

#3

投稿記事 by やんち » 9年前

これでどうでしょう。

コード:

#include <stdio.h>

/* #if sizeof(int)!=4*/
#if (__SIZEOF_INT__ != 4)
#error sizeof(int) must be 4
#endif/* (__SIZEOF_INT != 4) */

int main(void) {
    printf("Hello,World!\n");
    return 0;
}

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#4

投稿記事 by みけCAT » 9年前

maru さんが書きました:sizeofはプリプロセスでは処理されないからでしょうね。

コード:

#include "limits.h"
#if INT_MAX!=LONG_MAX
ではいかがでしょうか。
Longも4バイトでなかった場合、これではチェックできないと思います。
やんち さんが書きました:これでどうでしょう。

コード:

#include <stdio.h>
 
/* #if sizeof(int)!=4*/
#if (__SIZEOF_INT__ != 4)
#error sizeof(int) must be 4
#endif/* (__SIZEOF_INT != 4) */
 
int main(void) {
    printf("Hello,World!\n");
    return 0;
} 
#error sizeof(int) must be 4と言われてしまいました。
次のコードでは、ちゃんと
Hello,World!
4
と表示されます。

コード:

#include <stdio.h>

#if 0
/* #if sizeof(int)!=4*/
#if (__SIZEOF_INT__ != 4)
#error sizeof(int) must be 4
#endif/* (__SIZEOF_INT != 4) */
#endif/*0*/ 
 
int main(void) {
    printf("Hello,World!\n");
    printf("%d\n",sizeof(int));
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#5

投稿記事 by ISLe » 9年前

__SIZEOF_INT__ はgcc4で定義されますがgcc3では定義されないのですね。

コード:

#include <limits.h>
#if UINT_MAX != (1<<(CHAR_BIT*4))-1
#error sizeof(int) must be 4
#endif
これはどうでしょう。
Cygwin版gcc 3.4.4/gcc 4.3.4とvc++2010では使えました。

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#6

投稿記事 by みけCAT » 9年前

きちんとコンパイルできました。

コード:

#include <stdio.h>

#include <limits.h>
#if UINT_MAX != (1<<(CHAR_BIT*4))-1
#error sizeof(int) must be 4
#endif
 
int main(void) {
    printf("Hello,World!\n");
    return 0;
}
こうするとちゃんとエラーが出ました。

コード:

#include <stdio.h>

#include <limits.h>
#if UINT_MAX != (1<<(CHAR_BIT*2))-1
#error sizeof(int) must be 4
#endif
 
int main(void) {
    printf("Hello,World!\n");
    return 0;
}
ISLeさん、ありがとうございました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Justy
副管理人
記事: 122
登録日時: 9年前
住所: 神奈川県

Re: int型のサイズが4でなかったらエラー

#7

投稿記事 by Justy » 9年前

 sizeof(int)==4の評価をコンパイル時にしたいのであれば、これでいけるかもしれません。

コード:

#include <stdio.h>
 
#define static_assert_(eval) typedef char static_error_##__LINE__[(eval)?1: -1]
static_assert_(sizeof(int) == 4);
 
int main(void) {
    printf("Hello,World!\n");
    return 0;
}
[hr]# 12/28 19:53 __LINE__の評価のタイミング問題の為、下記のように訂正。

コード:

#include <stdio.h>

#define define_join2(A, B) define_join2_(A, B)
#define define_join2_(A, B) A ## B

#define static_assert_(eval) typedef char define_join2(static_error_,__LINE__)[(eval)?1: -1]
static_assert_(sizeof(int) == 4);

int main(void) {
    printf("Hello,World!\n");
    return 0;
}

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#8

投稿記事 by みけCAT » 9年前

Justy さんが書きました: sizeof(int)==4の評価をコンパイル時にしたいのであれば、これでいけるかもしれません。

コード:

#include <stdio.h>
 
#define static_assert_(eval) typedef char static_error_##__LINE__[(eval)?1: -1]
static_assert_(sizeof(int) == 4);
 
int main(void) {
    printf("Hello,World!\n");
    return 0;
}
これでもできました。
しかし、任意のエラーメッセージを出せないので、わかりにくいですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

YuO
記事: 941
登録日時: 9年前
住所: 東京都世田谷区

Re: int型のサイズが4でなかったらエラー

#9

投稿記事 by YuO » 9年前

みけCAT さんが書きました:

コード:

#if UINT_MAX != (1<<(CHAR_BIT*4))-1
これはundefined behaviorの可能性があります。ISO/IEC 9899:1999 6.5.7 Bitwise shift operators
If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.
つまり,ビットシフト演算子の右辺の値が左辺のサイズ以上だった場合はundfined behaviorなので,intがCHAR_BIT * 4以下のサイズしか持たない場合,undefined behaviorです。

なので,Justyさんの方法が安全で汎用性を持ちます。
エラーメッセージは変数名で頑張るしかないですが……。

アバター
Justy
副管理人
記事: 122
登録日時: 9年前
住所: 神奈川県

Re: int型のサイズが4でなかったらエラー

#10

投稿記事 by Justy » 9年前

 あ、gccだと __LINE__よりも先に ## を処理してしまいますね。
みけCAT さんが書きました:
Justy さんが書きました:任意のエラーメッセージを出せないので、わかりにくいですね。
 エラーメッセージに変数名を出す環境ならこれで多少はマシになるかも。

コード:

#include <stdio.h>

#define define_join4(A, B, C, D)	define_join4_(A, B, C, D)
#define define_join4_(A, B, C, D)	A ## B ## C ## D

#define static_assert_(eval, tag) typedef char define_join4(static_error_L, __LINE__, _, tag)[(eval)?1: -1]
static_assert_(sizeof(int) == 4, sizeof_int_must_be_4);

int main(void)
{
    printf("Hello,World!\n");
    return 0;
}

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#11

投稿記事 by みけCAT » 9年前

Justy さんが書きました: あ、gccだと __LINE__よりも先に ## を処理してしまいますね。
みけCAT さんが書きました:
Justy さんが書きました:任意のエラーメッセージを出せないので、わかりにくいですね。
 エラーメッセージに変数名を出す環境ならこれで多少はマシになるかも。

コード:

#include <stdio.h>

#define define_join4(A, B, C, D)	define_join4_(A, B, C, D)
#define define_join4_(A, B, C, D)	A ## B ## C ## D

#define static_assert_(eval, tag) typedef char define_join4(static_error_L, __LINE__, _, tag)[(eval)?1: -1]
static_assert_(sizeof(int) == 4, sizeof_int_must_be_4);

int main(void)
{
    printf("Hello,World!\n");
    return 0;
}
ありがとうございます。
試しにsizeof(int)==2としてみると、
size of array `static_error_L7_sizeof_int_must_be_4' is negative
と表示されました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ISLe
記事: 2645
登録日時: 9年前
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#12

投稿記事 by ISLe » 9年前

いまさらですが

コード:

#include <limits.h>
#if UINT_MAX != 0xffffffff
#error sizeof(int) must be 4
#endif
で必要十分な気がしました。
もしcharが16ビットだとsizeof(int)が4でも64ビットですけどそれは望まれてない気がするのですが。

gcc 3.4.2で使えるか分かりませんがinttypes.hをインクルードしてint32_t型などを使うようにすると環境を選ばなくなる気がします。

アバター
みけCAT
記事: 6247
登録日時: 9年前
住所: 千葉県
連絡を取る:

Re: int型のサイズが4でなかったらエラー

#13

投稿記事 by みけCAT » 9年前

ISLe さんが書きました:いまさらですが

コード:

#include <limits.h>
#if UINT_MAX != 0xffffffff
#error sizeof(int) must be 4
#endif
で必要十分な気がしました。
もしcharが16ビットだとsizeof(int)が4でも64ビットですけどそれは望まれてない気がするのですが。
おお。これはわかりやすくていいですね。

コード:

#include <stdio.h>

#include <limits.h>
#if UINT_MAX != 0xffffffff
#error sizeof(int) must be 4
#endif

int main(void) {
	printf("Hello,World!\n");
	return 0;
}
ありがとうございます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る