C言語なら俺に聞け 145
■ このスレッドは過去ログ倉庫に格納されています
Visual Studio 2017
#define offsetof(s,m) ((size_t)&(((s*)0)->m))
gcc 7.2.0
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
clang 6.0.0
#define offsetof(t, d) __builtin_offsetof(t, d)
borland 5.5.1
#define offsetof( s_name, m_name ) (_SIZE_T)&(((s_name _FAR *)0)->m_name) >>587
>ポインタ演算を使った式が整定数になる保証がないので別の手段を
ポインタ演算の結果が浮動小数点とか変数になる例早よう出しなされ メモリーの仕切り壁に落書きするポインタ
9と3/4番線ホームから出発する列車を指し示すポインタ
あれば便利かも知れないが(何がだ) 鉄道に例えるならポイント(線路の分岐)を制御するデコーダに与える信号がCのポインタだ >>591
その前に、まずはポインタ演算を使った結果が整定数になることが保証されている例を出してくれ。
当然規格は読んでいるよね。6.6p6より
> An integer constant expression shall have integer type and shall only have operands
> that are integer constants, enumeration constants, character constants,
> sizeof expressions whose results are integer constants, and floating constants that are the
> immediate operands of casts. 汎整数型定数をポインタにキャストまたは暗黙に変換した式は定数式(たとえば空ポインタ定数は定数式)
その定数式を整数にキャストし直した式が定数式でなくなる根拠はない >>595
先生!
>>587で 「ポインタ演算を使った式が整定数になる保証がないので別の手段を使っている場合がある。」
って言い切ってるんだから、その「場合」とやらを僕も知りたいです! >>596
>その定数式を整数にキャストし直した式が定数式でなくなる根拠はない
でもそれは整定数式ではないよね。
規格にはキャスト前の型が算術型でなければならないとある。
> Cast operators in an integer constant expression shall only convert arithmetic types to integer types, except as part of an operand to the
> sizeof operator. (配列等で)連続が保障されてるときには要素数が求まるようにはなってるけど
連続性のないポインタの差分は鼻から悪魔だったような
規格? みてない >>598
俺は根拠がないと言ったんだが
それをすっ飛ばして整定数式ではないと言われてもねえ a[b*c];
のようにしてもassemblyコードがアドレッシングモードじゃなくて
掛け算してしまうんですけどどうしたらアドレッシングモードで計算するように
なりますか? >>604
b と c とを使って何をしたいのでしょうか? >>604
何がしたいのかよくわからないけど、エスパーすると
Cソースで変数のセクションを指定して、リンカでそのセクションの配置を
期待するアドレスに配置すればいいんじゃないかな。 struct a{
int a;
int b;
};
struct a x[100];
void *v=x;
void *h(int n, int s){
return ((char *)v+n*s);
}
struct a *i(int n){
return &x[n];
}
同じことをしているのにhは掛け算するのにiは掛け算をアドレッシングモードでしているので
処理速度の差が生まれてしまいます。 struct aにキャストしてから計算すればいいという話ではなくて? sがなんだかわからないけど
void *h(int n, int s){
return ((struct a *)v+n*s);
}
じゃだめなん?
s=1ならi()と同じだと思うけど。 struct a *は8バイトなので8を入れればよいのです。 ブロックサイズみたいなイメージかな。
だったらsizeof(struct a)にしたほうがよいかと。 >>612
それは違う環境に持っていってコンパイルしたら破綻するかも知れない。
やはりsizeof使うかそのまんまポインタ計算させた方が良いのでは? struct a*のサイズは32-bit 環境だと4だよな。64ビットだと8バイト。 ポインタを操作するなら、size_tとかptrdiff_t使った方がいいな。 >>616
ここでは構造体の実体の配列だからsizeof(struct a)で大丈夫。
int1つのサイズは典型的には4byteだけど、IP64だのあまり見ない
データモデルでは8byteのこともあるから、構造体のサイズを使うときは
sizeofがよい(MAY)、ではなくてsizeofにすべき(ほぼMUSTのSHOULD)。 本買うならどれがいい?
本より優れたサイトがあるならそれでもいいぞ >>620
きつねさんとおぼえる clang
きつねさんとおぼえる clang おかわり struct a{
bool a:1;
uint32_t b:31;
uint16_t c;
};
struct a{
uint32_t b;
uint16_t c;
bool a;
};
上の構造体が12バイツでしたが8バイツの理由がわかりません、上を8バイツにしたいです。 C言語のboolって何バイト?
C++だとINTと等価なことがそれなりにあるんだけど。 >>622
よく分からないんだけど、2つ構造体を書いてるのは何を意図してるの? >>622
俺の環境ではどっちのsizeofの値も8バイツを返したから環境依存だろう。
#pragma か __attribute__ で詰め込めるかも知れんけど、
ビットフィールドを狙って使える指定方法があるかどうか。
詰めたら詰めたで6バイツや7バイツになっちゃう危険もあるし。
>>623
<stdbool.h> にどう書いてあるかだろうな。
これも試したら sizeof(bool) に1を返した。
<stdbool.h> の実体を思しきファイルを覗いたら
#define _Bool signed char
#define bool _Bool
の連鎖になってた。typedefでないのが少々意外。
#ifdef で定義済か未定義かを判定できるようにするためだろうか。 >622
uint32_t b; がバイト境界にひっかかったせいじゃね? alignment
Емельяненко
なんで日本人は「ん」を飛ばすかねえ 間抜けな回答してるな>オレ
||
||
∧||∧
( / ⌒ヽ
| | |
∪ / ノ
| ||
∪∪
-━━- >629
>なんで日本人は「ん」を飛ばすかねえ
「全て」の日本人が「ン」を飛ばすわけではありません。
「或る」日本人が「ン」を飛ばすだけです。
ところで、ロシア語の
Емельяненко(エメリャネンコ)
とはどういう意味ですか。手元の「ロ日辞典」をひいても
でていないので
struct a{
bool x:1;
uint32_t y:31;
};
しらべたらこれの大きさが8バイツでした
sizeof(struct a)とやったらそうなったのでアラインメントのもんだいではありません。
どうしても4バイツにしたいです もしかして変数を分解しようとしてる?
Unionってしってるかー? 構造体宣言に
__attribute__((packed))
を挟む C++なら、無名うにおんとかつかえて楽なんだけど、Cは一々名前がつくので面倒。 struct a{
uint32_t a:1;
uint32_t y:31;
};
こうやったらできました
ビットフィールドを勘違いしていたのが原因みたいです。 struct a{
union{
bool a:1;
struct{
uint32_t x:1;
uint32_t y:31;
};
};
};
つまりこうしたらよいのですね。
勉強になりました。ありがとうございます。 >>640
これ、bool aとuint32_t xが同じ値であることがどの環境下でも保証されてるの?
教えてエロい人 >>622
ビットフィールドって同じ型が並んでないとまとめてくれないのでは?
なので、
bool a:1;
uint32_t b:31;
ではなくて
uint32_t a:1;
uint32_t b:31;
にしたらできないか? 既に答えが出て解決していた
||
||
∧||∧
( / ⌒ヽ
| | |
∪ / ノ
| ||
∪∪
-━━- >>631
姓だよ、とある有名人の
国内ではエメリヤエンコということになっている https://ideone.com/GfSSSt
上のコードみてください。
なぜか上の構造体を使って初期化すると値がただしくなりません。
なぜですか? >>645
どこが正しくないのか説明してもらわないとたぶん誰も分からない https://ideone.com/WeAoO6
なにものかにコードが書き換えられたみたいです
正しくは上のコードを見てください。 >>647
struct a a={.y=1, .a=true};
ここを
struct a a={.a=true, .y=1,};
こう書き換えると動作が変わる。
何故変わるか考えてみよう。 struct になってない単変数でのビットフィールドって
結局支持された型の空間をめいっぱい使って書いてるんでないの >>648
直しました
>>649
考えてもわかりませんでした >>637-638 >>642
ビットフィールドの詰め込み方だけど、
「同じ型の並びならまとめる、異なる型同士はまとめない」、
「型に関係なくまとめる」、(他にもパターンあるかも…)、
どれになるかは環境依存だからアテにしてると移植性の問題にハマるよ。
ビットフィールドは内部的な配置を気にしない場合だけ使うのが鉄則。
>>622 の流れからすると、ビットフィールドを含む構造体は
sizeof が返すバイト数も気にしちゃいけないね。 >>647
unionの中にもう一つstruct
uint32_t b0:1; 〜 uint32_t b31:1;
を入れてみて、b0〜b31をオール0、その次はオール1にして
aやyに代入するたびにb0〜b31がどう変化するかを確かめればいいと思うよ。 >>652
コンパイラによっては型に関係なく並べるのもあるのか。知らなかった。 unionで共用関係作っても、詰め込み順が統一されてる保証は無いからなぁ。
んなトリッキーな処理は、移植ん時死ねるぞ。 ビットフィールドの順番がコンパイラによって違うのには参った >>657
エンディアンの違いで逆順になるのは昔からあるな。
コンパイルオプションでなんとかなるといいんだけどな。 いやあ、そんなドジ踏んだことないし
踏んだやつも見かけないなあ
unionなんか使うときはそういう危険性には
真っ向から対峙しているのでうっかり考え落とす
なんてことは起こりえない
ポインタをキャストするときのほうが危ないぞ
unionよりも遙かに使用頻度が高くて油断しがち 普段からアライメント気にしない石使ってると死ぬるw GOTOはその場所より基本上流に流しちゃいけない。
それだけ守ってればいいと思う。 if文とかfor文の中に飛ばすのもダメだろ
関数末尾以外に飛ばすのは基本アカンと思う >>667
switch と goto と聞いて、はっもしやこんなこともできるのでは、と思ってやってみたら、できてしまったよ。どうしよう。
#include <stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++) {
if (i == 5)
goto hoge;
switch (i) {
case 1:
puts("いち");
break;
hoge:
puts("ご");
break;
}
}
return 0;
} 情報処理用にC頑張り始めたンスけど、初心者本は2冊くらい終えて、簡単なプログラムならあるていど作れるようにもなったんスけど、FEの過去問には全く歯がたたないっすw 初見の歯抜けプログラムみて選択肢与えられてもなんだかさっぱり読み切れん…
中級本の内容の方がまだ簡単なんスけどニキこれなんなんすか Duff's deviceっていうスイッチの中にループがあるのもある >>676
int tmp = a;
a = b;
b = tmp;
もしくは
std::swap(a, b); a = a ^ b;
b = a ^ b;
a = a ^ b; >>677
mainから分離させると
void Swap()
{
std::swap(a,b);
}
こうなるってこと?? >>678
b の実体が a だと a = 0 になってしまう、とは頻繁に指摘されるところ void myswap(int *pa, int *pb)
{
int tmp = *pa;
*pa = *pb;
*pb = tmp;
} >>685
ソートとか、順番を変えるときとか、データの入れ替えなど。 ■ このスレッドは過去ログ倉庫に格納されています