473,748 Members | 2,574 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Some pointer quiestions again

According to Section A6.6 Pointers and Integers (k & R)

" A pointer to one type may be converted to a pointer to another type.
The resulting pointer may cause
addressing exceptions if the subject pointer does not refer to an
object suitably aligned in storage. It is
guaranteed that a pointer to an object may be converted to a pointer to
an object whose type requires less
or equally strict storage alignment and back again without change; the
notion of ``alignment'' is
implementation-dependent, but objects of the char types have least
strict alignment requirements. As
described in Par.A.6.8, a pointer may also be converted to type void *
and back again without change. "

It says that it is *guaranteed* that a pointer to an object may
be converted to an object whose type require equally stringent
storage alignment. My question is that since two pointer variables
may be of different size (as pointed out by lots of people
in this newsgroup ) how this could be possible ? It may be possible
that two pointer variables of different types have same
byte alignment restrictions but their sizes may be different. Under
these conditions how can we convert one to another ?

I would say that two pointer variables of different types
should never be allowed to convert from one type to other, because
same byte alignment does not mean same pointer variable size.

Secondly, section A.6.8 says that "previously char * pointers
played the role of generic (void) pointers"
Is this true presently also ?
Consider the following piece of code:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;

i = malloc(sizeof(i nt));
c = i;
}

On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced type of the
pointer value "i" is "int", which is not compatible with "unsigned
char". (ptrmismatch)
c = i;
--------^

If char pointer can play the role of generic pointer, why I
am getting this warning ?

Nov 14 '05 #1
16 2305
ju**********@ya hoo.co.in wrote:
According to Section A6.6 Pointers and Integers (k & R) " A pointer to one type may be converted to a pointer to another type.
The resulting pointer may cause
addressing exceptions if the subject pointer does not refer to an
object suitably aligned in storage. It is
guaranteed that a pointer to an object may be converted to a pointer to
an object whose type requires less
or equally strict storage alignment and back again without change; the
notion of ``alignment'' is
implementation-dependent, but objects of the char types have least
strict alignment requirements. As
described in Par.A.6.8, a pointer may also be converted to type void *
and back again without change. " It says that it is *guaranteed* that a pointer to an object may
be converted to an object whose type require equally stringent
storage alignment. My question is that since two pointer variables
may be of different size (as pointed out by lots of people
in this newsgroup ) how this could be possible ? It may be possible
that two pointer variables of different types have same
byte alignment restrictions but their sizes may be different. Under
these conditions how can we convert one to another ? I would say that two pointer variables of different types
should never be allowed to convert from one type to other, because
same byte alignment does not mean same pointer variable size.
If the sizes differ the compiler has to insert code (you should
but don't have to tell it by casting) to make the conversion work
out right. But it's only required to do so reasonably if the align-
ment restrictions of the type you convert to aren't stricter than
of the type you're converting from. A conversion of bit represen-
tations of pointers is not uncommon, e.g. a NULL pointer doesn't
have to have a binary representation where all bits are 0, but you
can compare a NULL pointer (e.g. returned by from malloc()) with
the value 0 anyway and the result must be true, even though the
NULL pointer when cast to an int (assuming equal sizes) wouldn't
result in the number 0 [1]. So the compiler has to insert code that
makes the result of this comparison come out correctly. And for a
legitimate conversion (i.e. one where the above rules about align-
ment restrictions are satisfied) between pointers of types which are
stored with different sizes the compiler also has to ensure that
this works correctly if it's a standard compliant C compiler [2].
Secondly, section A.6.8 says that "previously char * pointers
played the role of generic (void) pointers"
Is this true presently also ?
Consider the following piece of code:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i; i = malloc(sizeof(i nt));
c = i;
} On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced type of the
pointer value "i" is "int", which is not compatible with "unsigned
char". (ptrmismatch)
c = i;
--------^ If char pointer can play the role of generic pointer, why I
am getting this warning ?


It's a warning, not an error, telling you that you may be doing
something stupid. Not more and not less. The compiler will probably
assume that you know what you're doing when you would do the conver-
sion with an explicit cast (but it still could emit a warning, there
is no restriction in the standard what a compiler can complain about),
so it might let you get away with an explicit cast. But since an
assignment between different types is something potentially dangerous
the compiler here tries to help you. It's the same as getting a war-
ning for e.g.

if ( x = malloc( 100 * sizeof *x ) )

There's nothing inherently wrong with this, but most compilers will
still tell you that you may unintenionally be doing an assignment
instead of a comparison here since getting '=' and '==' mixed up
in an if-condition is such a common mistake.

Moreover, as you cite yourself, char pointers "previously " played
the role of generic pointers - that was before the C standard came
out, finally making the void pointer type mandatory and giving
it some magical qualities, i.e. requiring that all pointer types
can be converted to and from a void pointer (at the cost that
you can't dereference a void pointer). Actually, a char pointer
still has to have the same representation and alignment require-
ments as a void pointer, but since char pointers aren't a poor
mans "ersatz" for a true generic pointer anymore compilers tend
to point out also implicit conversions to a char pointer from a
different pointer type as suspicious.

Regards, Jens

[1] This is also the reason why forgetting to include <stdlib.h>
when you use malloc() and instead casting the return value
is not guaranteed to work. If <stdlib.h> isn't included the
compiler assumes that malloc() returns an int and thus mind-
lessly converts the return value of malloc() to an int (per-
haps even passing the value back to the caller via an data
only register - there are several architectures that have
different registers for data and addresses). Only then it does
the explicit conversion, now converting from an int to the
intended pointer type. But since a pointer is not necessarily
the same as its representation when interpreted as an int this
can result in "interestin g" and probably unintended results,
e.g. a NULL pointer returned by malloc() becoming converted
to a non-NULL pointer on a machine where a NULL pointer is
not represented by all bits 0.

[2] Obviously, the implementor of a compiler for a machine where
different pointer types have different sizes has some problems
on his hands. One possible solution would by to use the size
required by the largest pointer type for storing all pointers,
even if that would cost some additional memory. Another one
would be to give up one writing a standard compliant C com-
piler like they did for DOS, where they invented new qualifiers
for pointers (i.e. far, huge etc.). Or perhaps on the target
machine there are some special tricks to solve the problem
(i.e. having a special bit stored with small sized pointers
that gets set when a pointer value from a larger sized pointer
gets stored in it and then indicates that it doesn't hold the
"real" address but just a pointer to another address where the
full-sized address can be found. And there are probably some
more clever ways I wouldn't know about, not being a C compiler
implementor.
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.toerring.de
Nov 14 '05 #2
Mac
On Tue, 31 May 2005 17:45:08 +0000, Jens.Toerring wrote:

[snip]
[...] requiring that all pointer types
can be converted to and from a void pointer [...]


Isn't this supposed to be all _object_ pointer types or something like
that? What I am getting at is that ISTR that you cannot store a function
pointer in a void pointer.

--Mac

Nov 14 '05 #3
Mac <fo*@bar.net> wrote:
On Tue, 31 May 2005 17:45:08 +0000, Jens.Toerring wrote: [snip]
[...] requiring that all pointer types
can be converted to and from a void pointer [...]

Isn't this supposed to be all _object_ pointer types or something like
that? What I am getting at is that ISTR that you cannot store a function
pointer in a void pointer.


You're right, at last as far as I understand the standard only
conversion between object type pointers and a void pointer is
guaranteed to work. Allowing to convert between void and func-
tion pointers is listed as a "Common extension", so it's not
portable.
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.toerring.de
Nov 14 '05 #4
Mac wrote:
On Tue, 31 May 2005 17:45:08 +0000, Jens.Toerring wrote:

[snip]
[...] requiring that all pointer types
can be converted to and from a void pointer [...]


Isn't this supposed to be all _object_ pointer types or something like
that? What I am getting at is that ISTR that you cannot store a function
pointer in a void pointer.


Correct. A function pointer can be converted to a void pointer [1] but
cannot portably be converted back again. A function pointer can be
converted to a function pointer of another type and back again though.

[1] I am not sure that a function pointer can even be converted to a
void pointer reliably, if not then there would appear to be no portable
way to print the value of a function pointer. If anyone can point to a
spot in the Standard that clarifies this, feel free.

Rob Gamble

Nov 14 '05 #5
Je***********@p hysik.fu-berlin.de wrote:
ju**********@ya hoo.co.in wrote:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;
c = i;
}

On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced
type of the pointer value "i" is "int", which is not
compatible with "unsigned char". (ptrmismatch)


It's a warning, not an error.


Actually it is a constraint violation with a diagnostic
required. I think this means that if the compiler goes on to
produce an executable anyway, then the behaviour is undefined.

Nov 14 '05 #6
Old Wolf <ol*****@inspir e.net.nz> wrote:
Je***********@p hysik.fu-berlin.de wrote:
ju**********@ya hoo.co.in wrote:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;
c = i;
}
On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced
type of the pointer value "i" is "int", which is not
compatible with "unsigned char". (ptrmismatch)


It's a warning, not an error.

Actually it is a constraint violation with a diagnostic
required. I think this means that if the compiler goes on to
produce an executable anyway, then the behaviour is undefined.


Since a char pointer must follow the same alignment restrictions as
a void pointer (i.e. none that matter) shouldn't that assignment be
ok? I gueses I am too dense to see the constraint violation here. The
only constraint for the assignment operator I found is "An assignmen
operator shall have a modifiable lvalue as its lef operand." which is
guess isn't violated here. Can you clearify that for me?

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.toerring.de
Nov 14 '05 #7
Je***********@p hysik.fu-berlin.de wrote:

Old Wolf <ol*****@inspir e.net.nz> wrote:
Je***********@p hysik.fu-berlin.de wrote:
ju**********@ya hoo.co.in wrote:

#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;
c = i;
}

On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced
type of the pointer value "i" is "int", which is not
compatible with "unsigned char". (ptrmismatch)

It's a warning, not an error.

Actually it is a constraint violation with a diagnostic
required. I think this means that if the compiler goes on to
produce an executable anyway, then the behaviour is undefined.


Since a char pointer must follow the same alignment restrictions as
a void pointer (i.e. none that matter) shouldn't that assignment be
ok? I gueses I am too dense to see the constraint violation here. The
only constraint for the assignment operator I found is "An assignmen
operator shall have a modifiable lvalue as its lef operand." which is
guess isn't violated here. Can you clearify that for me?


A cast is required.

N869
6.5.16.1 Simple assignment
Constraints
[#1] One of the following shall hold:
-- the left operand has qualified or unqualified
arithmetic type and the right has arithmetic type;
-- the left operand has a qualified or unqualified version
of a structure or union type compatible with the type
of the right;
-- both operands are pointers to qualified or unqualified
versions of compatible types, and the type pointed to
by the left has all the qualifiers of the type pointed
to by the right;
-- one operand is a pointer to an object or incomplete
type and the other is a pointer to a qualified or
unqualified version of void, and the type pointed to by
the left has all the qualifiers of the type pointed to
by the right; or
-- the left operand is a pointer and the right is a null
pointer constant.
-- the left operand has type _Bool and the right is a
pointer.

--
pete
Nov 14 '05 #8
ju**********@ya hoo.co.in writes:
According to Section A6.6 Pointers and Integers (k & R)

" A pointer to one type may be converted to a pointer to another type.
The resulting pointer may cause
addressing exceptions if the subject pointer does not refer to an
object suitably aligned in storage. It is
guaranteed that a pointer to an object may be converted to a pointer to
an object whose type requires less
or equally strict storage alignment and back again without change; the
notion of ``alignment'' is
implementation-dependent, but objects of the char types have least
strict alignment requirements. As
described in Par.A.6.8, a pointer may also be converted to type void *
and back again without change. "

It says that it is *guaranteed* that a pointer to an object may
be converted to an object whose type require equally stringent
storage alignment. My question is that since two pointer variables
may be of different size (as pointed out by lots of people
in this newsgroup ) how this could be possible ? It may be possible
that two pointer variables of different types have same
byte alignment restrictions but their sizes may be different. Under
these conditions how can we convert one to another ?
Usually, you convert one pointer type to another by using a cast.

You were probably asking how the conversion can be done on the machine
level (i.e., what happens to the bits), and I told you instead how you
do it in a C program. But in fact, that's really all you need to
know. It's up to the compiler to figure out how to make the
conversion work properly, regardless of the relative sizes of the
types. It's like converting the int value 4 to type float and getting
4.0, or vice versa, even though there's no guarantee that they're the
same size.

In most implementations I'm familiar with, all object pointers happen
to be the same size. For an implementation on which different object
points have different sizes, I would expect that a pointer to a type
with the least strict alignment requirements would probably be bigger
than a pointer to a type with stricter alignment requirements. For
example, if type int is word-aligned, an int* can be represented as a
word pointer, which doesn't need to specify a byte within the word; a
byte pointer (char* or void*) might need to be bigger because it has
to contain more information. If an implementation follows this kind
of scheme, the rules in the standard imply that you can convert a
smaller pointer to a larger pointer without losing information, which
is perfectly sensible.

An system where word pointers (or something like that) are bigger than
byte pointers would probably be quite exotic. Presumably there would
be good reasons for its quirks (unless it's the DS9000, which doesn't
need to justify anything). Either a C implementation would have to
jump through some hoops to make everything work as the standard
specifies, or there wouldn't be a conforming C implementation on the
system.
I would say that two pointer variables of different types
should never be allowed to convert from one type to other, because
same byte alignment does not mean same pointer variable size.
Differing pointer sizes shouldn't be a problem.
Secondly, section A.6.8 says that "previously char * pointers
played the role of generic (void) pointers"
Is this true presently also ?
Consider the following piece of code:
#include <stdlib.h>
int main(void)
{
unsigned char *c;
int *i;

i = malloc(sizeof(i nt));
c = i;
}

On comlilation, I get the warning,
cc: Warning: t.c, line 8: In this statement, the referenced type of the
pointer value "i" is "int", which is not compatible with "unsigned
char". (ptrmismatch)
c = i;
--------^

If char pointer can play the role of generic pointer, why I
am getting this warning ?


You're getting a diagnostic because the types unsigned char* and int*
are not assignment compatible. char* pointers can still be used as
generic pointers, but the language doesn't go out of its way to make
it easy to do so. In particular, there are implicit conversions
between void* and any object pointer type, but not between char* and
any object pointer type.

If you used an explicit cast:

unsigned char *c;
int *i;

i = malloc(sizeof *i);
c = (unsigned char *)i;

the compiler wouldn't complain, and c would point to the first byte of
the allocated block of memory (or would be a null pointer if the
malloc failed).

A couple of tangential style points:

I changed "sizeof(int )" to "sizeof *i", for reasons that have been
discussed here just recently.

The name "i" is typically used for an integer variable used as an
index. Using it as the name of a pointer will lead to confusion.
Likewise for "c", thought this isn't quite as bad. It's not a big
deal in a tiny sample program like yours, but it's easier to stick to
good naming habits if you use them consistently.

--
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.
Nov 14 '05 #9
pete <pf*****@mindsp ring.com> wrote:
Je***********@p hysik.fu-berlin.de wrote:

Old Wolf <ol*****@inspir e.net.nz> wrote:
> Je***********@p hysik.fu-berlin.de wrote:
>> ju**********@ya hoo.co.in wrote:
>>
>>> #include <stdlib.h>
>>> int main(void)
>>> {
>>> unsigned char *c;
>>> int *i;
>>> c = i;
>>> }
>>
>>> On comlilation, I get the warning,
>>> cc: Warning: t.c, line 8: In this statement, the referenced
>>> type of the pointer value "i" is "int", which is not
>>> compatible with "unsigned char". (ptrmismatch)
>>
>> It's a warning, not an error.
> Actually it is a constraint violation with a diagnostic
> required. I think this means that if the compiler goes on to
> produce an executable anyway, then the behaviour is undefined.


Since a char pointer must follow the same alignment restrictions as
a void pointer (i.e. none that matter) shouldn't that assignment be
ok? I gueses I am too dense to see the constraint violation here. The
only constraint for the assignment operator I found is "An assignmen
operator shall have a modifiable lvalue as its lef operand." which is
guess isn't violated here. Can you clearify that for me?

A cast is required. N869
6.5.16.1 Simple assignment
Constraints
[#1] One of the following shall hold:
-- the left operand has qualified or unqualified
arithmetic type and the right has arithmetic type;
-- the left operand has a qualified or unqualified version
of a structure or union type compatible with the type
of the right;
-- both operands are pointers to qualified or unqualified
versions of compatible types, and the type pointed to
by the left has all the qualifiers of the type pointed
to by the right;
-- one operand is a pointer to an object or incomplete
type and the other is a pointer to a qualified or
unqualified version of void, and the type pointed to by
the left has all the qualifiers of the type pointed to
by the right; or
-- the left operand is a pointer and the right is a null
pointer constant.
-- the left operand has type _Bool and the right is a
pointer.


Thank you. I should have scrolled down a bit further...

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@p hysik.fu-berlin.de
\______________ ____________ http://www.toerring.de
Nov 14 '05 #10

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

Similar topics

10
1904
by: fabio de francesco | last post by:
Hi what do you think of the following? Why are we permitted to do that? And why the C++ Library doesn't stop someone willing to perfom that assignement (*a = 20)? #include <iostream> using std::cout;
193
9616
by: Michael B. | last post by:
I was just thinking about this, specifically wondering if there's any features that the C specification currently lacks, and which may be included in some future standardization. Of course, I speak only of features in the spirit of C; something like object-orientation, though a nice feature, does not belong in C. Something like being able to #define a #define would be very handy, though, e.g: #define DECLARE_FOO(bar) #define...
3
2037
by: Chris Saunders | last post by:
I am attempting to write and interface from another language to some C code. I am having some difficulty interpreting a declaration. int (*SSL_CTX_get_verify_callback(SSL_CTX *ctx))(int,X509_STORE_CTX *); Any help would be appreciated. Regards Chris Saunders chris.saunders@sympatico.ca
7
2215
by: Rano | last post by:
/* Hello, I've got some troubles with a stupid program... In fact, I just start with the C language and sometime I don't understand how I really have to use malloc. I've readden the FAQ http://www.eskimo.com/~scs/C-faq/faq.html but it doesn't seem to answer my questions... So, I've made an example behind, with some included questions...
204
13061
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 = {0,1,2,4,9};
16
2512
by: aegis | last post by:
Given the following: int a = 10; int *p; void *p1; unsigned char *p2; p = &a;
48
2171
by: yezi | last post by:
Hi, all: I want to record some memory pointer returned from malloc, is possible the code like below? int memo_index; int i,j; char *tmp; for (i=0;i<10;i++){
5
3371
by: Y2J | last post by:
I am working through this book on C++ programming, the author is speaking of using linked lists. He gave and example which I found confusing to say the least. So I rewrote the example in a way that I could better understand the concept, he was trying to convey to me. I ran my own example and it crashed and burn "what a surprise!" : (. I ran the authors example out of the book and quess what, it crashed also, : 0. I ran them both on my...
2
1771
by: xianwei | last post by:
First, typedef struct pair { Node *parent; Node *child; } Pair; static Pair SeekItem(cosnt Item *pI, const Tree *pTree) { Pair look;
0
8996
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
8832
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9562
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...
1
9333
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
9254
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
8255
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...
0
6078
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 into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3319
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

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.