473,722 Members | 2,468 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Help me understand this compiler warning.

I have a program written in C under Linux (gcc) which a user has
ported to run under AT&T SysV R4.

He sent me a copy of his makelog which displays a large number
of compiler warnings similar to this:

warning: semantics of ">>" change in ANSI C; use explicit cast

The statement to which this applies is:
xuc = ((uc[7] & 0xF0 ) >4);

where the declarations for xuc and uc are:
extern unsigned char xuc;
unsigned char uc[20];

I assume this warning means his compiler expects the number
4 in that statement to be cast as an unsigned char, but I
haven't yet found a warning level switch in my gcc compiler
which displays this warning, so can't be sure. There's no
such warning for another statement in the same function:
xi = uc[8] + (uc[9] << 8);

where in this case:
extern int xi;

Is his compiler being overly picky or is the (apparently
expected) cast something that should be done in well-written
C code?

(Note: the variable names shown are simplified for clarity;
the actual names used are much more self-explanatory).

Thanks for your help.

Regards,
Charles Sullivan

Aug 12 '06 #1
8 2008
Charles Sullivan (in pa************* *************** @triad.rr.com)
said:

| I have a program written in C under Linux (gcc) which a user has
| ported to run under AT&T SysV R4.
|
| He sent me a copy of his makelog which displays a large number
| of compiler warnings similar to this:
|
| warning: semantics of ">>" change in ANSI C; use explicit cast
|
| The statement to which this applies is:
| xuc = ((uc[7] & 0xF0 ) >4);
|
| where the declarations for xuc and uc are:
| extern unsigned char xuc;
| unsigned char uc[20];

Try:

xuc = ((uc[7] & 0xF0u) >4);

I'd use:

xuc = (uc[7] >4) & 0x0F;

to ensure that the shifted portion is not promoted to an int.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 12 '06 #2
Morris Dovey wrote:
>
Charles Sullivan (in pa************* *************** @triad.rr.com)
said:

| I have a program written in C under Linux (gcc) which a user has
| ported to run under AT&T SysV R4.
|
| He sent me a copy of his makelog which displays a large number
| of compiler warnings similar to this:
|
| warning: semantics of ">>" change in ANSI C; use explicit cast
|
| The statement to which this applies is:
| xuc = ((uc[7] & 0xF0 ) >4);
I think the compiler wants to see it this way:

xuc = (unsigned char)((uc[7] & 0xF0 ) >4);
|
| where the declarations for xuc and uc are:
| extern unsigned char xuc;
| unsigned char uc[20];

Try:

xuc = ((uc[7] & 0xF0u) >4);

I'd use:

xuc = (uc[7] >4) & 0x0F;

to ensure that the shifted portion is not promoted to an int.
I don't think that does what you want.

N869
6.5.7 Bitwise shift operators

[#3] The integer promotions are performed on each of the
operands.

--
pete
Aug 12 '06 #3

Charles Sullivan wrote:
I have a program written in C under Linux (gcc) which a user has
ported to run under AT&T SysV R4.

He sent me a copy of his makelog which displays a large number
of compiler warnings similar to this:

warning: semantics of ">>" change in ANSI C; use explicit cast

The statement to which this applies is:
xuc = ((uc[7] & 0xF0 ) >4);

where the declarations for xuc and uc are:
extern unsigned char xuc;
unsigned char uc[20];

I assume this warning means his compiler expects the number
4 in that statement to be cast as an unsigned char, but I
haven't yet found a warning level switch in my gcc compiler
which displays this warning, so can't be sure. There's no
such warning for another statement in the same function:
xi = uc[8] + (uc[9] << 8);

where in this case:
extern int xi;

Is his compiler being overly picky or is the (apparently
expected) cast something that should be done in well-written
C code?
This question is a very good question but not
an easy one to answer.

The warning is intended to alert a programmer to
a potential problem but which isn't a problem
in this case. The code as written will work
fine.

I myself wouldn't want to write a cast here. I
would if I had to to shut the compiler up, but
before that I would try

xuc = (uc[7] & 0xF0u) >4;

or

xuc = (uc[7] >4) & 0xF;

(probably in that order) and see if one of those
helped. If one did, I'd use that in preference
to casting.

Aug 12 '06 #4
pete (in 44**********@mi ndspring.com) said:

| Morris Dovey wrote:
||
|| Charles Sullivan (in pa************* *************** @triad.rr.com)
|| said:
||
||| I have a program written in C under Linux (gcc) which a user has
||| ported to run under AT&T SysV R4.
|||
||| He sent me a copy of his makelog which displays a large number
||| of compiler warnings similar to this:
|||
||| warning: semantics of ">>" change in ANSI C; use explicit cast
|||
||| The statement to which this applies is:
||| xuc = ((uc[7] & 0xF0 ) >4);
|
| I think the compiler wants to see it this way:
|
| xuc = (unsigned char)((uc[7] & 0xF0 ) >4);

Since xuc is unsigned. Casting the result isn't necessary in order for
the assignment to be made as intended. ANDing an unsigned char with an
int /could/ produce a signed int - which, according to 6.5.7(5), could
produce an implementation-defined shifted result.

Better to ensure that the quantity to be shifted is unsigned.

||| where the declarations for xuc and uc are:
||| extern unsigned char xuc;
||| unsigned char uc[20];
||
|| Try:
||
|| xuc = ((uc[7] & 0xF0u) >4);
||
|| I'd use:
||
|| xuc = (uc[7] >4) & 0x0F;
||
|| to ensure that the shifted portion is not promoted to an int.
|
| I don't think that does what you want.
|
| N869
| 6.5.7 Bitwise shift operators
|
| [#3] The integer promotions are performed on each of the
| operands.

You appear to have missed that part of 6.7.5(3) that says the result
will have the type of the promoted left operand - unsigned if done as
I suggest.

6.3.1.8(1) - rules for integer promotions - adds a bit of
clarification (sort of).

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 13 '06 #5
On Sat, 12 Aug 2006 21:25:56 GMT, Charles Sullivan
<cw******@triad .rr.comwrote in comp.lang.c:
I have a program written in C under Linux (gcc) which a user has
ported to run under AT&T SysV R4.

He sent me a copy of his makelog which displays a large number
of compiler warnings similar to this:

warning: semantics of ">>" change in ANSI C; use explicit cast
Prior to the adoption of the 1989/1990 ANSI/ISO standard, some
compilers applied different rules for promoting unsigned types.
The statement to which this applies is:
xuc = ((uc[7] & 0xF0 ) >4);

where the declarations for xuc and uc are:
extern unsigned char xuc;
unsigned char uc[20];
Assuming 8-bit characters, which is true of every Linux I have ever
heard of, then uc[7] has a value between 0 and 255 inclusive. Under
any ANSI/ISO version of C, this will cause uc[7] to be promoted to
signed int, since a signed int can hold all the values of an unsigned
char. This is called a "value preserving" promotion.

On the other hand, some pre-standard compilers performed what might be
called "unsigned preserving" promotions. Unsigned char promoted to
unsigned int and unsigned int promoted to unsigned long.

If the pre-standard C compiler for the AT&T implementation used the
old rules, the uc[7] would promote to an unsigned int with a value
between 0 and 255. This would cause a conversion of integer literal
0xF0 to unsigned int, and the bitwise and would be performed on the
two unsigned ints, producing an unsigned int result, which was finally
shifted right.

Under the new rules, uc[7] is promoted to a signed int with a value
between 0 and 255. Since the integer literal 0xF0 already has type
signed int, it is not converted and the bitwise and takes place on two
signed int values, generating a signed int result. This signed int
result is then shifted right.

There are potential surprises in right shifting signed ints (or signed
longs, for that matter) with negative values. It is
implementation-defined whether the sign bit is maintained or
discarded.

In this particular case, however, you will be right shifting a signed
int with a positive value, and this is absolutely well defined as long
as the shift count is within range, which is certainly is. Signed
integer types with a positive value are defined by the standard to
have identical bit representations as the corresponding unsigned types
with the same value, and right shifting yields the same result.

So due to the values used in this case, there is no actual possibility
of a different result on any implementation. With other values,
specifically those that involve right shifting a signed integer type
with a negative value, there could be a difference in the result. The
compiler is warning about the possibility in the abstract, not
checking to see whether it could happen with the specific values in
this particular case.
I assume this warning means his compiler expects the number
4 in that statement to be cast as an unsigned char, but I
That's a totally incorrect assumption. The type of the right operand,
the shift count, does not play any value at all in any promotion of
the left operand or the type of the result. If the type of the shift
count is less than int, it is promoted to either signed or unsigned
int, but the type on which the operation is performed, and the type of
the result, is based strictly on the promoted type of the left
operand.
haven't yet found a warning level switch in my gcc compiler
which displays this warning, so can't be sure. There's no
such warning for another statement in the same function:
xi = uc[8] + (uc[9] << 8);

where in this case:
extern int xi;

Is his compiler being overly picky or is the (apparently
expected) cast something that should be done in well-written
C code?

(Note: the variable names shown are simplified for clarity;
the actual names used are much more self-explanatory).

Thanks for your help.
The code is actually correct, well-defined, and fully portable. But
if you want to eliminate the warning, as Morris suggested, change the
type of the integer literal:

xuc = ((uc[7] & 0xF0u) >4);

This should eliminate it.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Aug 13 '06 #6
Morris Dovey wrote:
>
pete (in 44**********@mi ndspring.com) said:

| Morris Dovey wrote:
||
|| Charles Sullivan (in pa************* *************** @triad.rr.com)
|| said:
||
||| I have a program written in C under Linux (gcc) which a user has
||| ported to run under AT&T SysV R4.
|||
||| He sent me a copy of his makelog which displays a large number
||| of compiler warnings similar to this:
|||
||| warning: semantics of ">>" change in ANSI C; use explicit cast
|||
||| The statement to which this applies is:
||| xuc = ((uc[7] & 0xF0 ) >4);
|
| I think the compiler wants to see it this way:
|
| xuc = (unsigned char)((uc[7] & 0xF0 ) >4);

Since xuc is unsigned. Casting the result isn't necessary in order for
the assignment to be made as intended. ANDing an unsigned char with an
int /could/ produce a signed int - which, according to 6.5.7(5), could
produce an implementation-defined shifted result.

Better to ensure that the quantity to be shifted is unsigned.

||| where the declarations for xuc and uc are:
||| extern unsigned char xuc;
||| unsigned char uc[20];
||
|| Try:
||
|| xuc = ((uc[7] & 0xF0u) >4);
||
|| I'd use:
||
|| xuc = (uc[7] >4) & 0x0F;
||
|| to ensure that the shifted portion is not promoted to an int.
|
| I don't think that does what you want.
|
| N869
| 6.5.7 Bitwise shift operators
|
| [#3] The integer promotions are performed on each of the
| operands.

You appear to have missed that part of 6.7.5(3) that says the result
will have the type of the promoted left operand - unsigned if done as
I suggest.

6.3.1.8(1) - rules for integer promotions - adds a bit of
clarification (sort of).
The left operand is uc[7], which is of type unsigned char.

Your posted code doesn't do anything to prevent
type unsigned char from being promoted to type int.

Why do you think that in
(uc[7] >4)
that the left operand won't be promoted to int?

"If an int can represent all values of the original type, the
value is converted to an int; otherwise, it is converted to
an unsigned int. These are called the integer
promotions."

--
pete
Aug 13 '06 #7
pete (in 44**********@mi ndspring.com) said:

| The left operand is uc[7], which is of type unsigned char.
|
| Your posted code doesn't do anything to prevent
| type unsigned char from being promoted to type int.
|
| Why do you think that in
| (uc[7] >4)
| that the left operand won't be promoted to int?
|
| "If an int can represent all values of the original type, the
| value is converted to an int; otherwise, it is converted to
| an unsigned int. These are called the integer
| promotions."

You're absolutely right. I'm not sure how I managed it; but I looked
it up, read it carefully, and concluded that the unsigned char would
be promoted to an unsigned int - very wrong.

Thanks for getting me on track - and to the OP, my apologies for an
incorrect response.

--
Morris Dovey
DeSoto Solar
DeSoto, Iowa USA
http://www.iedu.com/DeSoto
Aug 13 '06 #8
Many thanks to all who responded - Morris Dovey, pete, ena8t8si,
and Jack Klein. I especially appreciate Jack's detailed explanation
of the historical background.

Regards,
Charles Sullivan

Aug 16 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
2145
by: xuatla | last post by:
Hi, I encountered the following compile error of c++ and hope to get your help. test2.cpp: In member function `CTest CTest::operator+=(CTest&)': test2.cpp:79: error: no match for 'operator=' in '*this = CTest::operator+(CTest&)((+t2))' test2.cpp:49: error: candidates are: CTest CTest::operator=(CTest&) make: *** Error 1
1
3186
by: Hafeez | last post by:
I am having real trouble compiling this code http://www.cs.wisc.edu/~vganti/birchcode/codeHier/AttrProj.tgz The attachment shows errors when compiled using the current version of g++ in a i386-pc-solaris2.9. Seeing reference to gcc-2.7.2 in the Makefile of the code, I downloaded it and compiled in my home directory. Then changed the referenes of LIBDIR and INCLUDES to this installation .and ran with g++ for 2.7.2 then there are still...
6
4907
by: Raja Koduru | last post by:
Hello everybody, I am not yet fully comfortable with understanding c++ warnings/error messages. Very recently I have updated my IDE to VC++7.0 (MS.Net 7.0-Enterprise architect) from vc++6. Initially the same code used to compile without any messages. Now the following warning/error messages are appearing. I don't think this it is related some source code of mine. Otherwise I would have pasted the my code here.
15
2744
by: Buck Rogers | last post by:
Hi guys! Task 1: Write a program which presents a menu with 5 options. The 5th option quits the program. Each option should execute a system command using system(). Below is my humble offering. =================================================== #include <stdio.h> #include <stdlib.h>
27
4761
by: MK | last post by:
I am a newbie. Please help. The following warning is issued by gcc-3.2.2 compiler (pc Linux): ================================================================== read_raw_data.c:51: warning: assignment makes pointer from integer without a cast ================================================================== when the following piece of code was compiled. The offending statement is calloc. A similar statement in the main() function...
16
1580
by: hoggmeister | last post by:
Hi, Im new to C coming from a java background. I having difficulty adjusting to C and was hoping someone could help me with a little simple code to get started. I would like a little program that outputs on to the console a message like "please enter some text" then when the user enters text it gets stored in a char array or whatever is best. I then want to check that the array is no longer than 25 chars ( i dont know if malloc is...
33
2858
by: Martin Jørgensen | last post by:
Hi, In continuation of the thread I made "perhaps a stack problem? Long calculations - strange error?", I think I now got a "stable" error, meaning that the error always seem to come here now (tried: visual studio 2005 + linux/macintosh gcc)... That's a pretty good thing. I think the error still appears using both gcc and visual studio 2005. Everything is standard C (ANSI C ?? I don't know the difference) - but since so many functions...
1
6415
by: Ian | last post by:
I've just discovered the msclr::lock class in the C++ Support Library online documentation. This seems like a much cleaner way to implement thread protection than using monitor::enter/try/finally/monitor exit. However, I cannot get around one of the warning messages and am requesting help in understanding what is causing the warning. All of the online sample code for the class msclr::lock generates the same warning message. I have...
2
2257
by: Thelma Lubkin | last post by:
I use my own matrix and vector classes. I wrote them before such things were generally available and I've stuck with them ever since. I've just added an Octonion class derived from the vectors class and I'm trying to do some matrix arithmetic where the elements of the matrices are Octonions. (My Octonions are essentially 8-component vectors with a multiplication table that I compute at runtime. Like vectors, they are a template class, but...
0
8867
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9386
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9239
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9158
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9090
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8059
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6685
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4503
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2606
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.