473,580 Members | 2,870 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

16 bit pointer typecast on 16 bit system

Hi,

What does ANSI C say about casting an 8 bit pointer to a 16 bit one,
when the byte pointer is pointing to an odd address? I have detected a
problem in the Samsung CalmShine 16 compiler. This compiler I use for
the Samsung 16 bit Smartcard chips and I want to know if it is
compliant with the ANSI standard or if it violates it.

Have a look at this super simple example, where the value of b is
incorrect:

#include <stdio.h>

// Define an array in the EEPROM memory at address 0x081000
char data[8]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} _at_
0x81000, eeprom;

int main ( void )
{
char a;
short b;
long c;
char* bpData;

// Set up the pointer to point to an odd address
bpData = &data[1];

// read a byte from an even address
a= *(bpData + 1);

// Read a word from an odd address. This causes problems. Instead of
// getting 0x0102 I get 0x001. What does ANSI C say about this?
b= *(short*)(bpDat a) ;

// just to check the value of the pointer, if the value of it is to
be stored in a variable
c= (long)bpData;

return 0x0 ;
}

Jul 3 '06 #1
17 2711
yes, you should get 0x102 (if it is Big-endian) or 0x201 (if it is
Little-endian) but definitely not 0x1.

I've confirned this with the following test program in gcc:

#include <stdio.h>
char a[] = {0,1,2,3,4};
short b;
int main()
{
b = *(short *)(a+1);
printf("b = 0x%x\n",b);
return 0;
}

It prints the result "b = 0x201" (on an x86, which is little-endian).
I'd say that your compiler is broken...

MQ.

Jul 3 '06 #2
mi************* *@gmail.com wrote:
yes, you should get 0x102 (if it is Big-endian) or 0x201 (if it is
Little-endian) but definitely not 0x1.

I've confirned this with the following test program in gcc:

#include <stdio.h>
char a[] = {0,1,2,3,4};
short b;
int main()
{
b = *(short *)(a+1);
printf("b = 0x%x\n",b);
return 0;
}

It prints the result "b = 0x201" (on an x86, which is little-endian).
I'd say that your compiler is broken...
I'd say your expectations are broken.

You take a value that isn't and never has been pointer-to-short, forcibly
convert it to pointer-to-short, and dereference it -- that sounds to me
like it would generate undefined behaviour.

--
Chris "seeker" Dollin
"I'm still here and I'm holding the answers" - Karnataka, /Love and Affection/

Jul 3 '06 #3
In article <11************ *********@a14g2 000cwb.googlegr oups.com"Christ ian Wittrock" <cu*@xponcard.d kwrites:
....
char* bpData;
....
bpData = &data[1];
....
// Read a word from an odd address. This causes problems. Instead of
// getting 0x0102 I get 0x001. What does ANSI C say about this?
b= *(short*)(bpDat a) ;
Undefined behaviour.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Jul 3 '06 #4
Christian Wittrock wrote:
Hi,

What does ANSI C say about casting an 8 bit pointer to a 16 bit one,
when the byte pointer is pointing to an odd address? I have detected a
problem in the Samsung CalmShine 16 compiler. This compiler I use for
the Samsung 16 bit Smartcard chips and I want to know if it is
compliant with the ANSI standard or if it violates it.

Have a look at this super simple example, where the value of b is
incorrect:

#include <stdio.h>

// Define an array in the EEPROM memory at address 0x081000
char data[8]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} _at_
0x81000, eeprom;

int main ( void )
{
char a;
short b;
long c;
char* bpData;

// Set up the pointer to point to an odd address
bpData = &data[1];

// read a byte from an even address
a= *(bpData + 1);

// Read a word from an odd address. This causes problems. Instead of
// getting 0x0102 I get 0x001. What does ANSI C say about this?
b= *(short*)(bpDat a) ;
It might cause a trap.
Or something else undefined could happen.

Just assemble the bytes the way you need them.
Assuming you have 8 bit chars,
a = bpData[0] << 8 & bpData[1];

(make the types unsigned btw.)
Jul 3 '06 #5
Hi All,

thanks for the feedback. I am not looking for solutions on how to code
this using byte operations only. The question is related to what the
ANSI C standard has to say about the behaviour when typecasting in a 16
bit (or 32/64 for that matter) processor.

Logically, then any code written in ANSI should be compilable for any
platform and run without problems (in theory ;-) ). And this example is
in ANSI C. But standards only go so far and there are always "holes"
where a certain behaviour is not mentioned or dealt with. Since I can't
remember all of the ANSI C standard....... :-(

The type cast comes in place to be able to traverse through incomming
data on a I/O interface. The data is formattet in TLV format (Tag,
Length, Value). That means that I can never be sure that a word is
located on an aligned address. I use the byte pointer as I only have
the need for one pointer (this is a highly embedded system so I only
create variables and pointers if they are needed). Then, if I have to
retrieve a word I typecast.

The processor in question is a pure 16 bit one. That means it always
read 16 bytes from a memory location and throws away any unwanted part.

Thanks,
Christian

Jul 3 '06 #6
Christian Wittrock wrote:
Hi All,

thanks for the feedback. I am not looking for solutions on how to code
this using byte operations only. The question is related to what the
ANSI C standard has to say about the behaviour when typecasting in a 16
bit (or 32/64 for that matter) processor.

Logically, then any code written in ANSI should be compilable for any
platform and run without problems (in theory ;-) ).
Not in theory, and not in practice.

The standard says what's allowable and what's required. "What's required"
is surprisingly limited: a compiler must generate diagnostics for
constraint violations, an implementation must permit items of various
minimal sizes, stuff like that. An implementation can run out of
resources and die at the drop of a hat (but not at the drop of a mere
cap).

But conforming to the standard is your best bet of writing portable
code, if that's what you're trying to write.
>
The type cast comes in place to be able to traverse through incomming
data on a I/O interface. The data is formattet in TLV format (Tag,
Length, Value). That means that I can never be sure that a word is
located on an aligned address. I use the byte pointer as I only have
the need for one pointer (this is a highly embedded system so I only
create variables and pointers if they are needed). Then, if I have to
retrieve a word I typecast.
You have a choice.

(a) either arrange always to use the same implementation and ensure
that it's document to do what you want. Since you're on some
embedded system, that might be a plausible tactic.

(b) Don't use casts that way: it's not portable. Do the right thing
instead: something like `p[0] + (p[1] << PROBABLYEIGHT)` . Of
course if the generated code for this is awful and it matters,
you may be stuck with (a).
The processor in question is a pure 16 bit one. That means it always
read 16 bytes from a memory location and throws away any unwanted part.
The Standard doesn't exhibit this much interest in implementation
detail. (And "any unwanted part" is interestingly ambiguous.)

--
Chris "rotate, mask -- pick one" Dollin
"No-one here is exactly what he appears." G'kar, /Babylon 5/

Jul 3 '06 #7
On 3 Jul 2006 03:24:56 -0700, "Christian Wittrock" <cu*@xponcard.d k>
wrote in comp.lang.c:
Hi,

What does ANSI C say about casting an 8 bit pointer to a 16 bit one,
The C standard says nothing at all about "8 bit pointers" and "16 bit
pointers". It talks about pointers to types, and those types can have
different sizes on different implementations . But we'll assume for
the moment that you know that characters have 8 bits and shorts 16
bits on your platform.
when the byte pointer is pointing to an odd address? I have detected a
problem in the Samsung CalmShine 16 compiler. This compiler I use for
the Samsung 16 bit Smartcard chips and I want to know if it is
compliant with the ANSI standard or if it violates it.
The C standard says that the behavior is undefined.
Have a look at this super simple example, where the value of b is
incorrect:

#include <stdio.h>

// Define an array in the EEPROM memory at address 0x081000
char data[8]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} _at_
0x81000, eeprom;
Actually the minute you use the non-standard extension "_at_ 0x81000,
eprom", you have left the realm of the C standard behind. This means
nothing at all in standard C.

But assuming this results in a valid pointer to char...
int main ( void )
{
char a;
short b;
long c;
char* bpData;

// Set up the pointer to point to an odd address
bpData = &data[1];
If the non-standard definition does indeed create an array of chars
that your program has the right to access, this is a valid assignment
and places the address value 0x81000 in bpData.

But notice that you could have replaced the two lines with a simple
initialization in the definition of the pointer:

char *bpData = data + 1;
// read a byte from an even address
a= *(bpData + 1);
This is perfectly legal code, and assigned the contents of the char at
0x81002 to 'a'.
// Read a word from an odd address. This causes problems. Instead of
// getting 0x0102 I get 0x001. What does ANSI C say about this?
b= *(short*)(bpDat a) ;
The C standard says that if you use a pointer to something other than
a character type to access something, and the object does not have the
type of the pointer, the behavior is undefined.

C also says that when you convert pointer types, as your conversion
using a cast above, the result is undefined if the pointer is not
properly aligned for the new type.

I assume this is either a 16 or 32 bit processor, DSP, or
microcontroller . Some of these do have alignment requirements, and
accessing a 16-bit value on an odd address will violate these. The
results include a value that you consider "wrong", to generating a
hardware exception. An ARM, for example, will generate an address
abort.

Have you read the documentation on the processor, DSP, or
microcontroller that you are using? What are its address alignment
requirements?
// just to check the value of the pointer, if the value of it is to
be stored in a variable
c= (long)bpData;

return 0x0 ;
}
Someone who programs embedded systems in C, using architectures
dissimilar to typical desk top processors, needs to know a fair bit
more the C standard, especially if you try to do things like pointer
punning.

--
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
Jul 3 '06 #8
"Christian Wittrock" <cu*@xponcard.d kwrites:
thanks for the feedback. I am not looking for solutions on how to code
this using byte operations only. The question is related to what the
ANSI C standard has to say about the behaviour when typecasting in a 16
bit (or 32/64 for that matter) processor.
Please provide some context when you post a followup. Google now
makes this reasonably easy to do, but you still need to trim anything
that's not relevant.
Logically, then any code written in ANSI should be compilable for any
platform and run without problems (in theory ;-) ).
Nope.

[snip]
The type cast comes in place to be able to traverse through incomming
data on a I/O interface. The data is formattet in TLV format (Tag,
Length, Value). That means that I can never be sure that a word is
located on an aligned address. I use the byte pointer as I only have
the need for one pointer (this is a highly embedded system so I only
create variables and pointers if they are needed). Then, if I have to
retrieve a word I typecast.

The processor in question is a pure 16 bit one. That means it always
read 16 bytes from a memory location and throws away any unwanted part.
You mean 16 bits, not 16 bytes, right?

Let's assume char is 8 bits and short is 16 bits. You have a 16-bit
short value stored in an array of char, and you can't guarantee that
it's aligned properly. If you attempt to read it directly as a short,
you'll invoke undefined behavior; on many real-world systems, it will
cause your program to crash.

The simplest way to extract data from a byte array is to use memcpy().
Since it (theoretically) copies a byte at a time, alignment won't be
an issue. If you copy the data into a declared object of type short,
the target is guaranteed to be aligned probably.

I'm assuming that byte order isn't an issue (e.g., that the short was
written into the byte array by the current program, or at least on the
current system). If that's not the case, you'll need to deal with
that; memcpy() won't do it for you.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jul 3 '06 #9
** SIGH ***

Your answer start out professionally but end as "I know all and you
know nothing"! Please do not post any replies if you do not have
respect for people.

I had assumed that people would disregard the EEPROM variable as the
question is not related to this. I did not explicitly write what
alignment the processor uses, as this is implicitly given in the
example. And again the alignment (odd or even) is not that relevant.
The question was in relation to pointer casting behaviour when
accessing non-aligned memory locations. Shall a compiler automatically
do the trick for you to be ANSI compliant or not. And excuse me for not
knowing the standard by heart.

The reason why I posted my question was because I was faced with the
claim that the compiler (in question) is not ANSI C compliant. First of
all I always retrieve 16 bit values( or larger) on systems like this
one by getting a single byte at a time (the code has to be platform
independant). But again, that was not the question. The question is the
casting and not whether this a the correct way to code.

For someone who claims to be an expert and who talks down to others, I
would expect a bit more insigth than this. And it not good practise to
initialise variables within the declaration. Keep in mind that quite a
few embedded systems are put into a ROM chip, thereby creating the need
for a patch system. To initialize variables in the declaration will
make the compiler put in code before you can do a call to the patch
system.

I apologize for this angry reply, but I just got p***** off. You should
repect others more and answer any post in a professional way.

/Christian


Jack Klein skrev:
On 3 Jul 2006 03:24:56 -0700, "Christian Wittrock" <cu*@xponcard.d k>
wrote in comp.lang.c:
Hi,

What does ANSI C say about casting an 8 bit pointer to a 16 bit one,

The C standard says nothing at all about "8 bit pointers" and "16 bit
pointers". It talks about pointers to types, and those types can have
different sizes on different implementations . But we'll assume for
the moment that you know that characters have 8 bits and shorts 16
bits on your platform.
when the byte pointer is pointing to an odd address? I have detected a
problem in the Samsung CalmShine 16 compiler. This compiler I use for
the Samsung 16 bit Smartcard chips and I want to know if it is
compliant with the ANSI standard or if it violates it.

The C standard says that the behavior is undefined.
Have a look at this super simple example, where the value of b is
incorrect:

#include <stdio.h>

// Define an array in the EEPROM memory at address 0x081000
char data[8]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07} _at_
0x81000, eeprom;

Actually the minute you use the non-standard extension "_at_ 0x81000,
eprom", you have left the realm of the C standard behind. This means
nothing at all in standard C.

But assuming this results in a valid pointer to char...
int main ( void )
{
char a;
short b;
long c;
char* bpData;

// Set up the pointer to point to an odd address
bpData = &data[1];

If the non-standard definition does indeed create an array of chars
that your program has the right to access, this is a valid assignment
and places the address value 0x81000 in bpData.

But notice that you could have replaced the two lines with a simple
initialization in the definition of the pointer:

char *bpData = data + 1;
// read a byte from an even address
a= *(bpData + 1);

This is perfectly legal code, and assigned the contents of the char at
0x81002 to 'a'.
// Read a word from an odd address. This causes problems. Instead of
// getting 0x0102 I get 0x001. What does ANSI C say about this?
b= *(short*)(bpDat a) ;

The C standard says that if you use a pointer to something other than
a character type to access something, and the object does not have the
type of the pointer, the behavior is undefined.

C also says that when you convert pointer types, as your conversion
using a cast above, the result is undefined if the pointer is not
properly aligned for the new type.

I assume this is either a 16 or 32 bit processor, DSP, or
microcontroller . Some of these do have alignment requirements, and
accessing a 16-bit value on an odd address will violate these. The
results include a value that you consider "wrong", to generating a
hardware exception. An ARM, for example, will generate an address
abort.

Have you read the documentation on the processor, DSP, or
microcontroller that you are using? What are its address alignment
requirements?
// just to check the value of the pointer, if the value of it is to
be stored in a variable
c= (long)bpData;

return 0x0 ;
}

Someone who programs embedded systems in C, using architectures
dissimilar to typical desk top processors, needs to know a fair bit
more the C standard, especially if you try to do things like pointer
punning.

--
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
Jul 4 '06 #10

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

Similar topics

1
2215
by: masood.iqbal | last post by:
I have a few questions regarding overloaded typecast operators and copy constructors that I would like an answer for. Thanks in advance. Masood (1) In some examples that I have seen pertaining to casting class A to class B, the implementation of the
9
3503
by: Arun Prasath | last post by:
Hi all, I have the following question regd pointer typecasting. Is the following type of pointer typecasting valid? #define ALLOC(type,num) ((type *)malloc(sizeof(type)*num)) /*begin code*/
10
4097
by: Kieran Simkin | last post by:
Hi, I wonder if anyone can help me, I've been headscratching for a few hours over this. Basically, I've defined a struct called cache_object: struct cache_object { char hostname; char ipaddr; };
2
2171
by: dis | last post by:
The following code introduces a 'generic function pointer' p. When calling the pointed-to function via this p, one has to typecast p towards a pointer to the type of the pointed-to function. My question is how to do this if the pointed-to function is a K&R style declared function, like f. The best I could come up with is a typecast towards a...
20
2064
by: j0mbolar | last post by:
I was reading page 720 of unix network programming, volume one, second edition. In this udp_write function he does the following: void udp_write(char *buf, <everything else omitted) struct udpiphdr *ui; struct ip *ip; ip = (struct ip *) buf;
19
8033
by: junky_fellow | last post by:
Can the size of pointer variables of different type may be different on a particular architecture. For eg. Can the sizeof (char *) be different from sizeof(int *) or sizeof (void *) ? What is the purpose of using a void pointer ? Instead of declaring a pointer variable "void *", can I declare it as "char *" and then later on typcast it...
22
28960
by: nick | last post by:
i do not know what is the use of (e.g. void *pt), when will use it. thanks!
22
2203
by: Brad | last post by:
Hi, Am trying to read one byte at location 0xFFF0 000E in an embedded system. I cast a pointer to int, then try to stuff the above address in, then reference whats at the location? wont compile, tried many different variations of this; any ideas appreciated.
41
4938
by: SRR | last post by:
Why is it discouraged to explicitly typecast the void pointer returned by malloc(); function? For example: { int *p; p = (int*)malloc(2*sizeof(int)); /*Explicit casting is done, therfore it is said to be a bad practice*/ /*Some codes*/ }
0
7854
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...
0
8132
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. ...
0
8296
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...
0
8157
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...
0
6533
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...
0
5349
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3790
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...
1
2295
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1118
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

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.