简体   繁体   English

如果将 int 传递给 C 中的字节参数会发生什么?

[英]What happens if you pass an int to a byte parameter in C?

How does C/C++ deal if you pass an int as a parameter into a method that takes in a byte (a char)?如果将 int 作为参数传递给接受字节(char)的方法,C/C++ 将如何处理? Does the int get truncated? int 会被截断吗? Or something else?或者是其他东西?

For example:例如:

void method1()
{
    int i = //some int;
    method2(i);
}

void method2(byte b)
{
     //Do something
}

How does the int get "cast" to a byte (a char)? int 如何“转换”为一个字节(一个字符)? Does it get truncated?它会被截断吗?

If byte stands for char type, the behavior will depend on whether char is signed or unsigned on your platform.如果byte代表char类型,则行为将取决于char在您的平台上是有符号的还是无符号的。

If char is unsigned, the original int value is reduced to the unsigned char range modulo UCHAR_MAX+1 .如果char是无符号的,则原始int值将减少到unsigned char范围模UCHAR_MAX+1 Values in [0, UCHAR_MAX] range are preserved. [0, UCHAR_MAX]范围内的值被保留。 C language specification describes this process as C 语言规范将此过程描述为

... the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. ...通过比新类型可以表示的最大值重复加或减1来转换值,直到该值在新类型的范围内。

If char type is signed, then values within [SCHAR_MIN, SCHAR_MAX] range are preserved, while any values outside this range are converted in some implementation-defined way.如果char类型是有符号的,则[SCHAR_MIN, SCHAR_MAX]范围内的值将被保留,而该范围外的任何值将以某种实现定义的方式进行转换。 (C language additionally explicitly allows an implementation-defined signal to be raised in such situations.) Ie there's no universal answer. (C 语言另外明确允许在这种情况下引发实现定义的信号。)即没有通用的答案。 Consult your platform's documentation.请查阅您平台的文档。 Or, better, write code that does not rely on any specific conversion behavior.或者,更好的做法是编写不依赖于任何特定转换行为的代码。

Just truncated AS bit pattern (byte is in general unsigned char, however, you have to check) Just truncated AS bit pattern(byte一般是unsigned char,不过你要核对一下)

int i = -1;诠释我= -1;

becomes成为

byte b = 255;字节 b = 255; when byte = unsigned char当 byte = unsigned char

byte b = -1;字节 b = -1; when byte = signed char当 byte = signed char

i = 0;我 = 0; b = 0; b = 0;

i = 1024;我 = 1024; b = 0; b = 0;

i = 1040;我 = 1040; b = 16; b = 16;

Quoting the C++ 2003 standard:引用 C++ 2003 标准:

Clause 5.2.2 paragrah 4: When a function is called, each parameter (8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding argument.条款 5.2.2 第 4 段:当调用 function 时,每个参数 (8.3.5) 应使用其相应的参数初始化 (8.5、12.8、12.1)。

So, b is initialized with i .因此, b是用i初始化的。 What does that mean?那是什么意思?

8.5/14 the initial value of the object being initialized is the (possibly converted) value of the initializer expression. 8.5/14 正在初始化的 object 的初始值是初始化表达式的(可能转换的)值。 Standard conversions (clause 4) will be used, if necessary, to convert the initializer expression to the … destination type;如有必要,将使用标准转换(第 4 条)将初始化表达式转换为……目标类型; no user-defined conversions are considered不考虑用户定义的转换

Oh, i is converted , using the standard conversions .哦, i转换的,使用标准转换 What does that mean?那是什么意思? Among many other standard conversions are these:许多其他标准转换包括:

4.7/2 If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2 n where n is the number of bits used to represent the unsigned type). 4.7/2 如果目标类型是无符号的,则结果值是与源 integer 一致的最小无符号 integer(模 2 n ,其中 n 是用于表示无符号类型的位数)。

4.7/3 If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); 4.7/3 如果目标类型是有符号的,并且可以在目标类型(和位域宽度)中表示,则值不变; otherwise, the value is implementation-defined.否则,该值是实现定义的。

Oh, so if char is unsigned, the value is truncated to the number of bits in a char (or computed modulo UCHAR_MAX+1, whichever way you want to think about it.)哦,所以如果char是无符号的,则该值将被截断为 char 中的位数(或计算模 UCHAR_MAX+1,无论您以何种方式考虑。)

And if char is signed, then the value is unchanged, if it fits;如果char是有符号的,则值不变,如果适合; implementation-defined otherwise.实现定义的,否则。

In practice, on the computers and compilers you care about, the value is always truncated to fit in 8 bits, regardless of whether char s are signed or unsigned.实际上,在您关心的计算机和编译器上,该值总是被截断以适合 8 位,无论char是有符号的还是无符号的。

You don't tell what a byte is, but if you pass a parameter that is convertible to the parameter type, the value will be converted.你不知道byte是什么,但是如果你传递一个可以转换为参数类型的参数,那么这个值就会被转换。

If the types have different value ranges there is a risk that the value is outside the range of the parameter type, and then it will not work.如果类型具有不同的值范围,则存在值超出参数类型范围的风险,然后它将无法工作。 If it is within the range, it will be safe.如果在这个范围内,那就是安全的。

Here's an example:这是一个例子:

1) Code: 1)代码:

#include <stdio.h>

void
method1 (unsigned char b)
{
  int a = 10;
  printf ("a=%d, b=%d...\n", a, b);
}

void
method2 (unsigned char * b)
{
  int a = 10;
  printf ("a=%d, b=%d...\n", a, *b);
}

int
main (int argc, char *argv[])
{
  int i=3;
  method1 (i);
  method2 (i);
  return 0;
}

2) Compile (with warning): 2)编译(有警告):

$ gcc -o x -Wall -pedantic x.c
x.c: In function `main':
x.c:22: warning: passing arg 1 of `method2' makes pointer from integer without a cast

3) Execute (with crash): 3)执行(崩溃):

$ ./x
a=10, b=3...
Segmentation fault (core dumped)

'Hope that helps - both with your original question, and with related issues. '希望对您的原始问题和相关问题有所帮助。

There are two cases to worry about:有两种情况需要担心:

// Your input "int i" gets truncated
void method2(byte b)
{
  ...

// Your "method2()" stack gets overwritten
void method2(byte * b)
{
  ...

It will be cast to a byte the same as if you casted it explicitly as (byte)i .它将被转换为一个字节,就像您将它显式转换为(byte)i一样。

Your sample code above might be a different case though, unless you have a forward declaration for method2 that is not shown.你上面的示例代码可能是不同的情况,除非你有一个未显示的method2的前向声明。 Because method2 is not yet declared at the time it is called, the compiler doesn't know the type of its first parameter.因为method2在调用时尚未声明,所以编译器不知道其第一个参数的类型。 In C, functions should be declared (or defined) before they are called.在 C 中,函数应该在调用之前声明(或定义)。 What happens in this case is that the compiler assumes (as an implicit declaration) that method2 's first parameter is an int and method2 receives an int .在这种情况下发生的是编译器假定(作为隐式声明) method2的第一个参数是一个int并且method2接收一个int Officially that results in undefined behaviour, but on most architectures, both int and byte would be passed in the same size register anyway and it will happen to work.正式这会导致未定义的行为,但在大多数体系结构中, intbyte无论如何都会在相同大小的寄存器中传递,并且它会碰巧起作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM