使用%运算符时出现警告 [英] Warnings when using % operator

查看:83
本文介绍了使用%运算符时出现警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一些示例代码,用于说明使用Hitachi

编译器获得的两个警告。当我使用GCC编译器时,我得到一个干净的编译。我会很感激

如果有人能够解释这些警告实际上意味着什么,因为他们反正对我来说是个很好的。


当我将LOOKUP_MAX的类型从size_t更改为int时,我在Hitachi编译器中得到了一个干净的

编译。


#include< stdio .h>

#define NELEMENTS(a)(sizeof(a)/ sizeof(a [0]))

用于便携式模运算的
/ *宏* /

#if(-1%2> 0)

#define IMOD(i,j)((i)%(j))

#else

#define IMOD(i,j)(((i)%(j))< 0?((i)%(j))+ j:(( i)%(j)))

#endif


char * lookup [] =

{

ABC,

" DEF",

" GHI",

" JKL"

};


const size_t LOOKUP_MAX = NELEMENTS(查询);


#include< stdio.h>


int main(无效)

{

int val;

/ * code where用户决定是否增加或减少价值

删除* /

/ * ... * /


/ *用户想要增加值,保持在[0,LOOKUP_MAX]范围内* /

val = IMOD(val + 1,LOOKUP_MAX);


/ *上述行代码产生两个警告:

*无符号比较总是真/假

*条件表达式总是真/假。

* /

返回0; / *成功* /

}


马丁
http://martinobrien.co.uk/

Below is some sample code to illustrate two warnings I get using a Hitachi
compiler. When I use the GCC compiler I get a clean compile. I''d be grateful
if someone could explain what the warnings actually mean as they are rather
crytic, to me anyway.

When I change the type of LOOKUP_MAX from size_t to int, I get a clean
compile in the Hitachi compiler.

#include <stdio.h>
#define NELEMENTS(a) (sizeof(a) / sizeof(a[0]))

/* macro for portable modulo operations */
#if (-1 % 2 > 0)
#define IMOD(i, j) ((i) % (j))
#else
#define IMOD(i, j) (((i) % (j)) < 0 ? ((i) % (j)) + j : ((i) % (j)))
#endif

char *lookup[] =
{
"ABC",
"DEF",
"GHI",
"JKL"
};

const size_t LOOKUP_MAX = NELEMENTS(lookup);

#include <stdio.h>

int main( void )
{
int val;
/* code where user decides whether to increment or decrement value
removed */
/* ... */

/* User wants to increment value, keep in range [0, LOOKUP_MAX] */
val = IMOD(val+1, LOOKUP_MAX);

/* The above line of code generates two warnings:
* Unsigned compare always true/false
* Conditional expression always true/false.
*/
return 0; /* success */
}

Martin
http://martinobrien.co.uk/

推荐答案

" Martin" ; < martin.o_brien @ [无垃圾邮件] which.net>写道:
"Martin" <martin.o_brien@[no-spam]which.net> writes:
#define IMOD(i,j)(((i)%(j))< 0?((i)%(j))+ j:(( i)%(j)))


[...]

val = IMOD(val + 1,LOOKUP_MAX);

/ *上面的代码行生成两个警告:
*无符号比较总是为真/假
*条件表达式总是为真/假。
* /
#define IMOD(i, j) (((i) % (j)) < 0 ? ((i) % (j)) + j : ((i) % (j)))
[...]
val = IMOD(val+1, LOOKUP_MAX);

/* The above line of code generates two warnings:
* Unsigned compare always true/false
* Conditional expression always true/false.
*/




当'a''和'b''无符号时,'a%b''总是非负的。

因此,((i)%(j)) <在这种情况下0总是假的,因此

第一次警告。那个子表达式是?:

表达式的第一部分,因此是第二个警告。


这种情况​​是GCC不会产生这些情况的原因警告

默认情况下。 (你可以用-W启用前者。)

-

Ben Pfaff

电子邮件: bl*@cs.stanford.edu

web: http://benpfaff.org


" Martin" < martin.o_brien @ [无垃圾邮件] which.net>写道:
"Martin" <martin.o_brien@[no-spam]which.net> writes:
[...]

/ *用于便携式模运算的宏* /
#if(-1%2> 0 )#define IMOD(i,j)((i)%(j))
#else
#define IMOD(i,j)(((i)%(j)) < 0?((i)%(j))+ j:((i)%(j)))
#endif
[...]

/* macro for portable modulo operations */
#if (-1 % 2 > 0)
#define IMOD(i, j) ((i) % (j))
#else
#define IMOD(i, j) (((i) % (j)) < 0 ? ((i) % (j)) + j : ((i) % (j)))
#endif




和其他有人解释说,难度产生了,因为

模数操作是无符号的,因为第二个操作数是

unsigned。


这个提出了一个有趣的挑战 - 如何编写IMOD

以便(1)它处理有符号和无符号

操作数的任意组合,以及(2)不会生成编译器警告,比如早期发布中提到的一个警告,比较一个

无符号值是否小于零?所需的语义

将返回最小的非负r,以便


i == m * j + r


,m和r是整数。为简单起见,请随意使用
假设j!= 0并且''r''的值可以表示为''i%j j'类型的值''。


那么,我是否正确地认为在符合标准的

汇编中,表达式'' - 1%2> 0''总是为零(

是,假)?



As other people have explained, the difficulty arose because the
modulo operation was done unsigned because the second operand was
unsigned.

This brings up an interesting challenge - how can IMOD be written
so that (1) it handles any combination of signed and unsigned
operands, and (2) doesn''t generate compiler warnings like the
one mentioned in the earlier posting caused by comparing an
unsigned value to be less than zero? The desired semantics
are to return the smallest non-negative ''r'' such that

i == m * j + r

with ''m'' and ''r'' being integers. For simplicity feel free to
assume that j != 0 and the value of ''r'' can be represented as
a value of the type of ''i % j''.

By the way, am I right in thinking that in a standard-compliant
compilation the expression ''-1 % 2 > 0'' will always be zero (that
is, false)?


Tim Rentsch写道:
Tim Rentsch wrote:
这带来了一个有趣的挑战 - 如何编写IMOD
以便(1)它处理有符号和无符号操作数的任意组合,以及(2)不会产生类似编译器的警告通过比较
无符号值小于零引起的早期帖子中提到的一个?理想的语义是返回最小的非负r,这样就可以使用m来表示我的='m * j + r

''和''r'是整数。为简单起见,请随意假设j!= 0且''r''的值可以表示为''i%j'类型的值。


两者都不需要假设:0< = r< | j |,%取j的类型。

答案对我来说似乎很简单 - 之前转换,而不是之后转换:


#define IMOD(i ,j)((i)< = 0 \

?((j)< = 0?-j - (( - i)%( - j)):j - (( -i)%(j)))\

:((j)< = 0?(i)%( - j):( i)%(j)))


然后,如果我= = m * j + r,那么以下所有内容也都成立:

i ==(-m)*( - j)+ r / / i pos,j neg

-i ==(m-1)*( - j) - j - r // i neg,j neg,-j> r

-i ==(m-1)* j + j - r // i neg,j pos,j> r

其余部分都是可能的最小正面,因为

它们都是正面的并且全部< j。


我通过使用i< = 0"

和j<来避免编译器对无符号i和j的警告; = 0"而不是i< 0"和j< 0" (我们使用哪个
分支并不重要)。这是一个完整的样本,运行和生成

正确的答案,没有警告gcc -Wall:


#include< stdio.h>


#define IMOD(i,j)((i)< = 0 \

?((j)< = 0?-j - ( (-i)%( - j)):j - (( - i)%(j)))\

:((j)< = 0?(i)%( - j):( i)%(j)))

int main(){

printf("%d%d%d%d% d \ n",IMOD(5u,3u),IMOD(5,3),IMOD(-5,3),

IMOD(5,-3),IMOD(-5, - 3));

返回0;

}

顺便说一句,我是否正确地认为符合标准的
编译表达式'' - 1%2> 0''将始终为零(
是,false)?
This brings up an interesting challenge - how can IMOD be written
so that (1) it handles any combination of signed and unsigned
operands, and (2) doesn''t generate compiler warnings like the
one mentioned in the earlier posting caused by comparing an
unsigned value to be less than zero? The desired semantics
are to return the smallest non-negative ''r'' such that

i == m * j + r

with ''m'' and ''r'' being integers. For simplicity feel free to
assume that j != 0 and the value of ''r'' can be represented as
a value of the type of ''i % j''.
Neither assumption is needed: 0 <= r < |j|, and % takes the type of j.
The answer seems simple to me - transform before, not afterwards:

#define IMOD(i,j) ((i) <= 0 \
? ((j) <= 0 ? -j - ((-i) % (-j)) : j - ((-i) % (j))) \
: ((j) <= 0 ? (i) % (-j) : (i) % (j)))

Then, if i == m*j + r, then all the following also hold:
i == (-m)*(-j) + r // i pos, j neg
-i == (m-1)*(-j) - j - r // i neg, j neg, -j > r
-i == (m-1)*j + j - r // i neg, j pos, j > r
The remainder parts are all the smallest positive possible, since
they''re all positive and all < j.

I''m avoiding the compiler warning for unsigned i and j by using "i <= 0"
and "j <= 0" rather than "i < 0" and "j < 0" (it doesn''t matter which
branch we use for zero). Here''s a complete sample that runs and produces
correct answers with no warnings with gcc -Wall:

#include <stdio.h>

#define IMOD(i,j) ((i) <= 0 \
? ((j) <= 0 ? -j - ((-i) % (-j)) : j - ((-i) % (j))) \
: ((j) <= 0 ? (i) % (-j) : (i) % (j)))

int main() {
printf("%d %d %d %d %d\n", IMOD(5u,3u), IMOD(5,3), IMOD(-5,3),
IMOD(5,-3), IMOD(-5,-3));
return 0;
}
By the way, am I right in thinking that in a standard-compliant
compilation the expression ''-1 % 2 > 0'' will always be zero (that
is, false)?




不。 如果两个操作数都是非负的,那么余数是

非负;如果没有,余数的符号是​​

实现定义。 - ISO C ++标准,5.6

但是,这个承诺中有一个隐含的约束:

"(a / b)* b + a%b等于

但我们知道乘法和整数除法如何表现;如果你工作

它出来,(a / b)* b必须有a的标志,并且不能从零开始

而不是a。因此,如果a是负数,则%b必须是非正数,

为了返回。到了。同样,如果a是正数,则%b必须是非负的,而不考虑b的符号,以满足此约束。我认为几乎所有的实现都忽略了这一点。

-

Derrick Coetzee

我授予此权限新闻组发布到公共领域。我不承担所有

明示或暗示保证并承担所有责任。我不是专业人士。



Nope. "If both operands are nonnegative then the remainder is
nonnegative; if not, the sign of the remainder is
implementation-defined." - ISO C++ Standard, 5.6

However, there is an implicit constraint in this promise:
"(a/b)*b + a%b is equal to a"
But we know how multiplication and integer division behave; if you work
it out, (a/b)*b must have the sign of a, and be no further from zero
than a. Consequently, if a is negative, a%b must be nonpositive, in
order to "get back" to a. Similarly, if a is positive, a%b must be
nonnegative, regardless of the sign of b, to satisfy this constraint. I
think pretty much all implementations overlooked this, though.
--
Derrick Coetzee
I grant this newsgroup posting into the public domain. I disclaim all
express or implied warranty and all liability. I am not a professional.


这篇关于使用%运算符时出现警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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