Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #22691 > unrolled thread
| Started by | Myth__Buster <raghavanil4m@gmail.com> |
|---|---|
| First post | 2012-06-25 09:08 -0700 |
| Last post | 2012-06-25 13:17 -0700 |
| Articles | 6 on this page of 26 — 11 participants |
Back to article view | Back to comp.lang.c
Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 09:08 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2012-06-25 09:16 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 12:08 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc James Kuyper <jameskuyper@verizon.net> - 2012-06-25 15:27 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-25 15:30 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 12:47 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-25 16:10 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-06-25 20:42 +0100
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 13:14 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Ian Collins <ian-news@hotmail.com> - 2012-06-26 08:30 +1200
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 13:53 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Ian Collins <ian-news@hotmail.com> - 2012-06-26 09:00 +1200
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc James Kuyper <jameskuyper@verizon.net> - 2012-06-25 17:13 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 13:58 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Owen Jacobson <angrybaldguy@gmail.com> - 2012-06-26 00:03 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc James Kuyper <jameskuyper@verizon.net> - 2012-06-25 16:47 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc gordonb.vk4xa@burditt.org (Gordon Burditt) - 2012-06-25 16:06 -0500
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Keith Thompson <kst-u@mib.org> - 2012-06-25 14:17 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-06-25 17:24 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc James Kuyper <jameskuyper@verizon.net> - 2012-06-25 12:52 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Myth__Buster <raghavanil4m@gmail.com> - 2012-06-25 12:28 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc James Kuyper <jameskuyper@verizon.net> - 2012-06-25 15:59 -0400
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Keith Thompson <kst-u@mib.org> - 2012-06-25 14:08 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Nobody <nobody@nowhere.com> - 2012-06-26 21:29 +0100
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Keith Thompson <kst-u@mib.org> - 2012-06-25 13:13 -0700
Re: Different sizes of data and function pointers on a machine -- void* return type of malloc, calloc, and realloc Paul N <gw7rib@aol.com> - 2012-06-25 13:17 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | Myth__Buster <raghavanil4m@gmail.com> |
|---|---|
| Date | 2012-06-25 12:28 -0700 |
| Message-ID | <63070d51-7bf5-4d64-a4a1-7c626cb1e237@googlegroups.com> |
| In reply to | #22696 |
On Monday, June 25, 2012 9:52:22 AM UTC-7, James Kuyper wrote:
> On 06/25/2012 12:08 PM, Myth__Buster wrote:
> > In reference with the below code,
> >
> > #include <stdlib.h>
> > #include <stdio.h>
> >
> > int f(void)
> > {
> > printf("\n In f . . . \n");
> > }
> >
> > int main(void)
> > {
> > int (*p)(void) = malloc(sizeof(int (*)(void)));
>
> "The pointer returned if the allocation succeeds is suitably aligned so
> that it may be assigned to a pointer to any type of object ..."
> (7.22.3p1). Note carefully that this only applies to pointers to object
> types, not function types.
>
> The code above converts a pointer to void into a pointer to a function
> type. The behavior of this code is well-defined if malloc() fails,
> because 6.3.6.2p4 says "Conversion of a null pointer to another pointer
> type yields a null pointer of that type." However, the behavior of this
> code is undefined if malloc() returns a non-null pointer "by omission of
> any explicit definition of the behavior" (4p2). The only other
> conversion defined by the standard that involves function pointer types
> is the conversion from one function pointer type to another (6.3.6.3p8),
> which doesn't apply here.
>
> > return 0;
> > }
> >
> > I would like to question about the return type of malloc(calloc, and
> > realloc).
>
> All three functions behave the same, as far as the issue raided by your
> message is concerned.
>
> > Assume that the above code runs on a machine wherein the data
> > pointers and function pointers are of different sizes. Then, what
> > malloc returns is a function pointer ...
>
> That's incorrect - what gave you that idea? The rest of your message
> depends upon that misconception, so I'll just stop here.
Well, am aware of the possible implications of converting a void* into a function pointer. But, the initialization of function pointer p is present only for the completeness of the code. For the question being discussed, let's consider the code as under :
#include <stdlib.h>
int main(void)
{
(void)malloc(sizeof(int (*)(void))); // Ignore the usability of this statement, possible
// memory-leaks, and any other trivial factors involved
// which are irrelevant to the question being discussed.
return 0;
}
Now, would like to reiterate myself - malloc() returns a void*(data pointer as always known) even when we have allocated memory for a function pointer on a machine wherein data and function pointers are of different sizes. This behavior of malloc appears to me as improper and hence I am questioning its generality of returning a void*(data pointer) always. Shouldn't there be a note in malloc's documentation regarding such usage?
Cheers,
Raghavan Santhanam
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-06-25 15:59 -0400 |
| Message-ID | <4FE8C322.9010604@verizon.net> |
| In reply to | #22703 |
On 06/25/2012 03:28 PM, Myth__Buster wrote:
...
> Well, am aware of the possible implications of converting a void* into a function pointer. But, the initialization of function pointer p is present only for the completeness of the code. For the question being discussed, let's consider the code as under :
>
> #include <stdlib.h>
> int main(void)
> {
> (void)malloc(sizeof(int (*)(void))); // Ignore the usability of this statement, possible
> // memory-leaks, and any other trivial factors involved
> // which are irrelevant to the question being discussed.
> return 0;
> }
>
> Now, would like to reiterate myself - malloc() returns a void*(data pointer as always known) even when we have allocated memory for a function pointer on a machine wherein data and function pointers are of different sizes. This behavior of malloc appears to me as improper and hence I am questioning its generality of returning a void*(data pointer) always. Shouldn't there be a note in malloc's documentation regarding such usage?
That depends upon what the problem is that you're talking about, which I
do not yet understand. If it is a problem with the specification of
malloc() provided by the C standard, then by definition the
documentation of malloc() already mentions it, if only implicitly. If
it's a problem with a particular implementation of malloc(), I agree
with you that the implementation's documentation for malloc() should be
modified to mention it.
Could you provide an example of code that would cause problems due to
the impropriety you perceive? The above code has no problems worse than
a memory leak. malloc() allocates enough space to store a pointer to a
function type, even if that space is larger than would be needed to
store a pointer to an object type. The function pointer itself has an
object type, and malloc() returns a void* pointer that can be converted
to pointer to a function pointer of that type, which is itself a data
pointer, and therefore, on such an implementation, has a different size.
Let me provide my own example, based upon yours, which may clarify the
issue for you:
#include <stdlib.h>
int f(void) {
printf("f() will return 1.\n");
return 1;
}
int main(void)
{
int (**p)(void) = malloc(sizeof *p);
if(p)
{
printf("p() returned %d\n", (*p)());
free(p);
}
return 0;
}
Now, *p has a pointer-to-function type: int (*)(void). p itself has a
pointer-to-data type: int (**)(void). On a machine such as you describe,
sizeof p would be different from sizeof *p. If all pointers on that
machine have only one of those two sizes, then sizeof(void*), the size
of the pointer that is returned by malloc(), will certainly be the same
as sizeof p, not sizeof *p. I get the impression that you consider this
problematic. Could you provide an explanation or at least an example of
how you think this could be problematic?
Note: under modern C rules, (*p)() could also have been written as
simply p(), without change in meaning. This is a syntactic convenience,
but potentially confusing. In this context I thought I should avoid any
unnecessary potential confusion.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-25 14:08 -0700 |
| Message-ID | <ln1ul36qx0.fsf@nuthaus.mib.org> |
| In reply to | #22703 |
Myth__Buster <raghavanil4m@gmail.com> writes:
[...]
> Well, am aware of the possible implications of converting a void* into
> a function pointer. But, the initialization of function pointer p is
> present only for the completeness of the code. For the question being
> discussed, let's consider the code as under :
>
> #include <stdlib.h>
> int main(void)
> {
> (void)malloc(sizeof(int (*)(void)));
> // Ignore the usability of this statement, possible
> // memory-leaks, and any other trivial factors involved
> // which are irrelevant to the question being discussed.
> return 0;
> }
>
> Now, would like to reiterate myself - malloc() returns a void*(data
> pointer as always known) even when we have allocated memory for a
> function pointer on a machine wherein data and function pointers are
> of different sizes. This behavior of malloc appears to me as improper
> and hence I am questioning its generality of returning a void*(data
> pointer) always. Shouldn't there be a note in malloc's documentation
> regarding such usage?
The expression
sizeof(int (*)(void))
yields a value of type size_t. The particular value is likely to be 4
or 8 on many typical systems.
malloc() only sees this value as its parameter; it doesn't know or care
that it happens to be the size of a function pointer. So you might as
well have written:
(void)malloc(4);
or
(void)malloc(8);
malloc will attempt to allocate that many bytes of memory, and will
return a void* value that points to it (or a null pointer if the
allocation fails).
If you like, you can then use that allocated memory as an object of
pointer-to-function type. There's nothing problematic about that. A
function pointer is just another data type, like an object pointer, an
integer, a floating-point object, or a struct object.
But if you want to use malloc() to allocate an object of some type, you
need to convert the result to a pointer to that type. Your original
code didn't do that correctly; it attempted to convert the result of
malloc() to a pointer-to-function type rather than to a
pointer-to-pointer-to-function type.
A typedef might make this a bit clearer:
typedef void (*func_ptr)(void);
...
func_ptr *p = malloc(sizeof *p);
p is a pointer to a pointer to function.
Another thing that you might *think* you can do is to set a function
pointer to point to space allocated by malloc():
func_ptr wrong = malloc(some_size);
For this to work, some_size would probably have to indicate the size of
the function. (That's assuming function pointers are implemented as
pointers to the function's code, which is not specified; a function
pointer might instead point to some kind of descriptor, for
example). You'd also need some way to initialize the newly allocated
memory so it acts like a function. This can be done on some systems, but
it's *extremely* system-specific.
What I *think* you're trying to do is allocate a single
pointer-to-function object using malloc() (that's the closest thing to
the code you showed us that makes any sense). But it's not clear *why*
you're doing this. If you're only allocating space for a single pointer
object, why not just declare the object directly?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Nobody <nobody@nowhere.com> |
|---|---|
| Date | 2012-06-26 21:29 +0100 |
| Message-ID | <pan.2012.06.26.20.29.43.683000@nowhere.com> |
| In reply to | #22703 |
On Mon, 25 Jun 2012 12:28:40 -0700, Myth__Buster wrote: > Now, would like to reiterate myself - malloc() returns a void*(data > pointer as always known) even when we have allocated memory for a function > pointer on a machine wherein data and function pointers are of different > sizes. This behavior of malloc appears to me as improper Why? > and hence I am questioning its generality of returning a void*(data > pointer) always. All pointers are data, and all pointers to data are data pointers, including pointers to function pointers. If you malloc() space for a function pointer, malloc returns a pointer to that space. Whether or not you actually use that space to hold a function pointer is irrelevant.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-06-25 13:13 -0700 |
| Message-ID | <lna9zr6tfn.fsf@nuthaus.mib.org> |
| In reply to | #22691 |
Myth__Buster <raghavanil4m@gmail.com> writes:
> In reference with the below code,
>
> #include <stdlib.h>
> #include <stdio.h>
>
> int f(void)
> {
> printf("\n In f . . . \n");
> }
>
> int main(void)
> {
> int (*p)(void) = malloc(sizeof(int (*)(void)));
>
> return 0;
> }
The above code is invalid; it contains a constraint violation, and any
conforming compiler must at least emit a diagnostic for it.
malloc() returns a result of type void*. You're attempting to use that
result to initialize an object of type int(*)(void), i.e., a
pointer-to-function type.
Initialization imposes the same type requirements as simple assignment.
Section 6.5.16.1 of N1570 lists the valid combinations of types for a
simple assignment; the list does not include this case.
There's an implicit conversion from void* to any pointer-to-object
type. There is no such implicit conversion from void* to any
pointer-to-function type.
> I would like to question about the return type of malloc(calloc, and
> realloc).
>
> Assume that the above code runs on a machine wherein the data pointers
> and function pointers are of different sizes. Then, what malloc
> returns is a function pointer but after casting it to void* while
> returning(Or, after assigning it to a void* variable internally and
> returning its value).
>
> Now, isn't malloc giving us the truncated address in the above
> context? Consider the same question applicable to calloc and realloc
> when used in such a context.
If you make the conversion explicit, using a cast, then I believe there
is no constraint violation:
int (*p)(void) = malloc(sizeof(int (*)(void)));
However the standard says nothing about the behavior of a conversion
from void* to a pointer-to-function type, so the behavior is undefined
by omission. The standard says nothing about "truncating" pointer
values; it simply doesn't define the result or behavior of the
conversion.
The authors of gcc apparently interpret the standard differently; with
"-std=c99 -pedantic", gcc 5.7 warns:
warning: ISO C forbids conversion of object pointer to function pointer type [-pedantic]
I'll post to comp.std.c and see if I can get this clarified.
What is your code intended to do? If you're trying to allocate space
for a single function pointer, then you need a
pointer-to-pointer-to-function to point to it.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Paul N <gw7rib@aol.com> |
|---|---|
| Date | 2012-06-25 13:17 -0700 |
| Message-ID | <695bb1cf-dd11-4944-b680-b49439c90d55@n33g2000vbi.googlegroups.com> |
| In reply to | #22691 |
On Jun 25, 5:08 pm, Myth__Buster <raghavani...@gmail.com> wrote:
> In reference with the below code,
>
> #include <stdlib.h>
> #include <stdio.h>
>
> int f(void)
> {
> printf("\n In f . . . \n");
>
> }
>
> int main(void)
> {
> int (*p)(void) = malloc(sizeof(int (*)(void)));
>
> return 0;
>
> }
>
> I would like to question about the return type of malloc(calloc, and realloc).
>
> Assume that the above code runs on a machine wherein the data pointers and function pointers are of different sizes. Then, what malloc returns is a function pointer but after casting it to void* while returning(Or, after assigning it to a void* variable internally and returning its value).
>
> Now, isn't malloc giving us the truncated address in the above context? Consider the same question applicable to calloc and realloc when used in such a context.
I'm not sure what you're trying to do. Is your idea to make a copy of
f and then stomp all over the code of the copy so that it does
something different from f itself? Or are you simply wanting to call
already-existing functions?
If you are really trying to re-write a function, then you will need to
know a lot about how your particular system works. For instance, you
will need to know how big the function is, which I don't think
standard C can tell you.
If, instead, you simply have several functions and you want to use a
function pointer to call them, then it's probably easiest just to use
a variable of type pointer-to-function and not mess about with malloc
at all.
Hope that helps.
Paul.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web