2

GCC を使用して次の C プログラムをコンパイルしようとしていますが、7 行目でエラーが発生しtaus88_t*ますmake_taus88(seed);

error: incompatible types when initializing type 'struct taus88_t *' using type 'taus88_t'|

使用してみましtaus88_t TAUS88 = make_taus88(6346456);たが、より多くのエラー/警告が表示されます。

taus88main.c||In function 'main':|
taus88main.c|8|error: incompatible type for argument 1 of 'taus88u32'|
taus88.h|21|note: expected 'struct taus88_t *' but argument is of type 'taus88_t'|
taus88main.c|9|error: incompatible type for argument 1 of 'taus88f32'|
taus88.h|22|note: expected 'struct taus88_t *' but argument is of type 'taus88_t'|
taus_88_cpp\taus88main.c|9|warning: unused variable 'numberf32'|
taus_88_cpp\taus88main.c|8|warning: unused variable 'numberu32'|

プロジェクトは以下の 3 つのファイルにあります。

taus88main.c

#include "taus88.h"
#include <stdint.h>

int main()
{

    taus88_t* TAUS88 = make_taus88(6346456);
    u32 numberu32 = taus88u32(TAUS88);
    f32 numberf32 = taus88f32(TAUS88);

    return 0;
}

taus88.h

#ifndef _COMMON_TAUS88_H
#define _COMMON_TAUS88_H

#include <stdint.h>
typedef int8_t    i8;
typedef int16_t   i16;
typedef int32_t   i32;
typedef int64_t   i64;

typedef uint8_t   u8;
typedef uint16_t  u16;
typedef uint32_t  u32;
typedef uint64_t  u64;
typedef float  f32;
typedef double f64;

typedef struct {u32 s1, s2, s3;} taus88_t;

taus88_t make_taus88(u32 seed);
u32 taus88u32(taus88_t *t);
f32 taus88f32(taus88_t *t);

#endif

taus88.c

#include <stdint.h>
#include "taus88.h"

taus88_t make_taus88(u32 seed)
{
  taus88_t t;
  t.s1 = 1243598713U ^ seed; if (t.s1 <  2) t.s1 = 1243598713U;
  t.s2 = 3093459404U ^ seed; if (t.s2 <  8) t.s2 = 3093459404U;
  t.s3 = 1821928721U ^ seed; if (t.s3 < 16) t.s3 = 1821928721U;
  return t;
}

u32 taus88u32(taus88_t *t)
{
  t->s1 = ((t->s1 &  -2) << 12) ^ (((t->s1 << 13) ^  t->s1) >> 19);
  t->s2 = ((t->s2 &  -8) <<  4) ^ (((t->s2 <<  2) ^  t->s2) >> 25);
  t->s3 = ((t->s3 & -16) << 17) ^ (((t->s3 <<  3) ^  t->s3) >> 11);
  return t->s1 ^ t->s2 ^ t->s3;
}

f32 taus88f32(taus88_t *t)
{
  union {u32 i ; f32 f ;} u;
  u.i = 0x3F800000 | (taus88u32(t) >> 9);
  return u.f - 1.0;
}
4

3 に答える 3

4

したがって、ここでの主な問題は、 a を返し、それを有効ではないtaus8_ta に割り当てようとしていることtaus88_t *です。コードからは明らかでない理由でポインターを使用する必要がある場合、修正は次のようになります。

taus88_t* TAUS88 = malloc(sizeof(taus88_t)) ;

*TAUS88 = make_taus88(6346456);

free完了したら、ポインターを呼び出すことを忘れないでください。より簡単なアプローチは、ポインターの使用をスキップして、次のようにすることです。

taus88_t TAUS88 ;

TAUS88 = make_taus88(6346456);
u32 numberu32 = taus88u32(&TAUS88);
f32 numberf32 = taus88f32(&TAUS88);

これで、もう電話を気にする必要はありませfreeん。

私が指摘したもう 1 つの問題は、ルールtaus88f32に違反している可能性が最も高いということです。strict aliasing

于 2013-07-27T03:16:56.393 に答える
0

taus88_t* TAUS88 = make_taus88(6346456);のように 2 行に分割するのはどうでしょうか。

taus88_t* TAUS88;
*TAUS88 = make_taus88(6346456);

http://ideone.com/KVbf79

于 2013-07-27T03:02:41.123 に答える
0

結果を a (へのポインタ)に代入しようとしているときmake_taus88に a を返すようですtaus88_ttaus88_t *taus88_t

したがって、最初の大きな問題は、ローカルでmake_taus88定義tしてから、それを返そうとすることです。make_taus88終了tすると範囲外になるため、それはできません。

taus88_t2 つ目は、 ではなく を返していることですtaus88_t *

tのように宣言し、のようなものを使用して動的に初期化することtaus88_t *で、両方を修正できます。次に、戻ることができ、それは正しい型になり、ヒープに割り当てられるため、スコープ外に出てもメモリは引き続き使用できます。make_taus88malloctmake_taus88

make_taus88また、フォームのすべての参照を に変更する必要があることに注意してt.s1くださいt->s1

于 2013-07-27T03:11:23.617 に答える