比特字段和整体提升 [英] Bit-fields and integral promotion

查看:72
本文介绍了比特字段和整体提升的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我正在使用int为16位的实现。

在下面的程序中,在第一种情况下调用了什么函数,

和什么在第二种情况下调用?

另外,如果C89和C99之间存在差异,我会想知道。

我已经尝试过不同的编译器,我看到了一些差异。

在我向C供应商提交错误报告之前,我想知道
知道正确的行为是什么。


struct S

{

unsigned int a:4;

unsigned int b:16 ;

};


void foo(void);

void bar(void);


int main(无效)

{

struct S s;

sa = 0;

sb = 0;


if(sa - 5< 0)

foo();

else

bar();


if(sb - 5< 0)

foo();

否则

吧();


返回0;

}

Carsten Hansen

Suppose I''m using an implementation where an int is 16 bits.
In the program below, what function is called in the first case,
and what is called in the second case?
Also, if there is a difference between C89 and C99, I would
like to know.
I have tried with different compilers, and I see some differences.
Before I file a bug report with my C vendor, I would like to
know what the correct behavior is.

struct S
{
unsigned int a:4;
unsigned int b:16;
};

void foo(void);
void bar(void);

int main(void)
{
struct S s;
s.a = 0;
s.b = 0;

if (s.a - 5 < 0)
foo();
else
bar();

if (s.b - 5 < 0)
foo();
else
bar();

return 0;
}
Carsten Hansen

推荐答案

Carsten Hansen写道:
Carsten Hansen wrote:

假设我正在使用一个实现int是16位。
在下面的程序中,在第一种情况下调用什么函数,
和第二种情况下调用的是什么?
另外,如果C89和C89之间存在差异C99,我想知道。
我尝试过不同的编译器,我看到了一些差异。
在我向C供应商提交错误报告之前,我想
struct S
{
unsigned int a:4;
unsigned int b:16;
};

void foo(void);
void bar(void);

int main(void)
{
struct S s;
sa = 0;
sb = 0;

if(sa - 5< 0)foo();
else> bar();
if(sb - 5< 0)foo();
else bar();
返回0;
}

Suppose I''m using an implementation where an int is 16 bits.
In the program below, what function is called in the first case,
and what is called in the second case?
Also, if there is a difference between C89 and C99, I would
like to know.
I have tried with different compilers, and I see some differences.
Before I file a bug report with my C vendor, I would like to
know what the correct behavior is.

struct S
{
unsigned int a:4;
unsigned int b:16;
};

void foo(void);
void bar(void);

int main(void)
{
struct S s;
s.a = 0;
s.b = 0;

if (s.a - 5 < 0) foo();
else > bar();
if (s.b - 5 < 0) foo();
else bar();
return 0;
}




(为了清晰起见,报价略有重新格式化)


foo和bar。未签名的永远不会少于0.


-

"如果您想通过groups.google.com发布后续内容,请不要使用

破损的回复链接在文章的底部。点击

" show options"在文章的顶部,然后点击

回复在文章标题的底部。 - Keith Thompson



(quote slightly reformatted for clarity)

foo and bar, respectively. An unsigned can never be less than 0.

--
"If you want to post a followup via groups.google.com, don''t use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


>假设我正在使用int为16位的实现。


不会改变任何东西。问题不在于16。就在那里

而不是unsigned。无符号变量只能是正数

(它们没有任何符号。)一个有符号变量可以选择

正数或负数 - 尽管它不会是能够像一个无数的值一样大的数字

(在底部更多地解释。)
> Suppose I''m using an implementation where an int is 16 bits.

doesn''t change anything. The problem isn''t the "16" that is in there
but rather the "unsigned." Unsigned variables can only be positive
(they have no sign.) A signed variable has the option to be either
positive or negative--though it won''t be able to be as big of a number
as an unsigned value (explained more at the bottom.)
在下面的程序中调用的是什么函数第一种情况,
和第二种情况下的内容是什么?


看起来像bar()bar()给我,这意味着我或者Falconer是间隔出来的
。如果它永远不会是负数,那么它永远不会比0更低,所以这两个的第一个语句应该是假的,并且将调用
bar()。

另外,如果C89和C99之间存在差异,我会想知道。


我的规格很轻,所以没有评论。

我尝试过不同的编译器,我看到了一些差异。
In the program below what function is called in the first case,
and what is called in the second case?
Looks like bar() bar() to me which means that either I or Falconer is
spacing out. If it can never be negative, then it will never be less
than 0 so the first statement for both of these should be false and
bar() will be called.
Also, if there is a difference between C89 and C99, I would
like to know.
I''m a lightweight on the specifications so no comment.
I have tried with different compilers, and I see some differences.




如果不同的编译器给出了不同的结果,我最好的选择是:b
有些人正在做他们应该做的事情并且不允许未签名的

值小于0,而其他人试图变得聪明

并且无形地纠正程序员的错误。虽然我不会说第二个聪明的是b / b。编译器是错误的我当然不会b $ b想要使用它。错误最好由您纠正,而不仅仅是消失

基于您开发的一些特殊怪癖

环境 - 否则您的环境瞬间变化,一切

停止了。


回到签名与未签名的主题,表示这些

值的方式完全相同:


16位价值

1111111111111111 = 65535

1111111111111111 = -1


计算机知道你指的是哪一个的唯一方法就是当你指定int时或unsigned int。基于此,它将以两种完全不同的方式处理相同的

精确位。

具体而言,无符号数字会像这样增长:

0 = 0

1 = 1

10 = 2

11 = 3

100 = 4

101 = 5

110 = 10

....

1111111111111101 = 65533
1111111111111110 = 65534

1111111111111111 = 65535


签名的数字是相同的,直到第16位


0 = 0

1 = 1

10 = 2

11 = 3

.. ..

111111111111101 = 32765 // 15位

111111111111110 = 32766

111111111111111 = 32767

1000000000000000 = - 32768 // 16位

1000000000000001 = -32767

1000000000000010 = -32766

....

1111111111111101 = -3

1111111111111110 = -2

1111111111111111 = -1


最后,单词hello < - 只有一堆和

零。这只是你告诉你的电脑应该如何解释它的问题。

0010 1101 0100 0011 0110 1000 0111 0010 0110 1001 0111 0011



If different compilers are giving different results, my best bet would
be that some are doing what they should do and not allowing an unsigned
value to be less than 0, while as others are trying to be intelligent
and correct the programmer''s mistakes invisibly. While I wouldn''t say
that the second "intelligent" compiler is buggy I certainly wouldn''t
want to use it. Bugs are best corrected by you and not merely disappear
based on some particular quirk of your development
environment--otherwise the instant your environment changes, everything
comes to a halt.

And back to the topic of signed versus unsigned, the way that these
values are represented is exactly the same:

16 bit value
1111111111111111 = 65535
1111111111111111 = -1

The only way for your computer to know which one you meant is when you
specify "int" or "unsigned int." Based on that it will treat the same
exact bits in two entirely different ways.
To be specific, an unsigned number grows like this:

0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
101 = 5
110 = 10
....
1111111111111101 = 65533
1111111111111110 = 65534
1111111111111111 = 65535

A signed number is the same up until the 16th bit

0 = 0
1 = 1
10 = 2
11 = 3
....
111111111111101 = 32765 //15 bits
111111111111110 = 32766
111111111111111 = 32767
1000000000000000 = -32768 //16 bits
1000000000000001 = -32767
1000000000000010 = -32766
....
1111111111111101 = -3
1111111111111110 = -2
1111111111111111 = -1

In the end, the word "hello" <- right there is just a bunch of ones and
zeroes. It is all just a matter of how you tell your computer it should
interpret it.
0010 1101 0100 0011 0110 1000 0111 0010 0110 1001 0111 0011


" Chris Williams" <第******** @ yahoo.co.jp>在消息中写道

news:11 ********************** @ c13g2000cwb.googlegr oups.com ...
"Chris Williams" <th********@yahoo.co.jp> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
看起来像bar()bar()给我,这意味着我或者Falconer是间隔的。如果它永远不会是负数,那么它永远不会少于0,所以这两个的第一个语句应该是假的,并且将调用
bar()。
Looks like bar() bar() to me which means that either I or Falconer is
spacing out. If it can never be negative, then it will never be less
than 0 so the first statement for both of these should be false and
bar() will be called.




什么永远不会消极? sa不能,但是sa-5可以。

6.7.2.1p9:位字段被解释为有符号或无符号整数类型

由...指定的位数。 s.a的类型是4位

无符号类型。由于这种类型的所有值都可以用

int表示,整数提升将其转换为int而不是unsigned int,

和sa-5的值是-5而不是UINT_MAX-4。



What can never be negative? s.a can''t, but s.a-5 can.
6.7.2.1p9: "A bit-field is interpreted as a signed or unsigned integer type
consisting of the specified number of bits." The type of s.a is a 4-bit
unsigned type. Since all the values of such a type can be represented by
int, the integer promotions convert it to int rather than to unsigned int,
and the value of s.a-5 is -5 rather than UINT_MAX-4.


这篇关于比特字段和整体提升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆