Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How do you cast an integer to a pointer?

56 views
Skip to first unread message

James Van Buskirk

unread,
Oct 12, 2007, 10:05:15 PM10/12/07
to
I can't see how to cast an integer to a pointer.
Here is my latest attempt:

C:\gfortran\test\dodecahedron>type bug1.f90
! bug1.f90

program main
use ISO_C_BINDING
implicit none
integer(C_INTPTR_T) p
type(C_PTR) cptr
! character(kind=C_CHAR), pointer :: c

p = 0
cptr = C_PTR(p+1)
! call C_F_POINTER(cptr, c)
end program main
C:\gfortran\test\dodecahedron>c:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran
-
Wall bug1.f90 -obug1
bug1.f90: In function 'MAIN__':
bug1.f90:10: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.

--
write(*,*) transfer(0.64682312090346863D-153,(/'X'/));end


Richard Maine

unread,
Oct 12, 2007, 10:17:16 PM10/12/07
to
James Van Buskirk <not_...@comcast.net> wrote:

> I can't see how to cast an integer to a pointer.

You can't. Fortran doesn't do that - not even with the C interop stuff.
Of course,you can always play around with TRANSFER, but recall that the
standard says that the resulting values are undefined when you type
cheat with TRANSFER. And you can do it in C.

> cptr = C_PTR(p+1)

I suppose you are trying to use a structure constructor here. You can't
do that with C_PTR as it has (intentionally) private components. The
whole point of private components is to keep you from fiddling with the
innards. You can't write a structure constructor for a private component
- you don't even know what the components are. Now maybe you know what a
C pointer better look like inside, but accordingh to the Fortran
compiler, you don't know.

> bug1.f90:10: internal compiler error: Segmentation fault

Well, of course, you know teh usual commentary about internal compiler
errors anyway.

--
Richard Maine | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle | -- Mark Twain

Rich Townsend

unread,
Oct 12, 2007, 10:20:13 PM10/12/07
to
Richard Maine wrote:
> James Van Buskirk <not_...@comcast.net> wrote:
>
>> I can't see how to cast an integer to a pointer.
>
> You can't. Fortran doesn't do that - not even with the C interop stuff.
> Of course,you can always play around with TRANSFER, but recall that the
> standard says that the resulting values are undefined when you type
> cheat with TRANSFER. And you can do it in C.

Well, given that James is the all-time king of TRANSFER() trickery, I expect a
(non-portable, but working) solution within a day!

;)

James Van Buskirk

unread,
Oct 13, 2007, 3:23:27 AM10/13/07
to
"Richard Maine" <nos...@see.signature> wrote in message
news:1i5vxdj.de6ci015o7a18N%nos...@see.signature...

> James Van Buskirk <not_...@comcast.net> wrote:

>> I can't see how to cast an integer to a pointer.

> You can't.

Oh, I didn't know it was that easy to do. Problem solved; thanks
for your help.

glen herrmannsfeldt

unread,
Oct 13, 2007, 9:18:30 AM10/13/07
to
Richard Maine wrote:
> James Van Buskirk <not_...@comcast.net> wrote:

>>I can't see how to cast an integer to a pointer.

> You can't. Fortran doesn't do that - not even with the C interop stuff.
> Of course,you can always play around with TRANSFER, but recall that the
> standard says that the resulting values are undefined when you type
> cheat with TRANSFER. And you can do it in C.

You can't do it portably in C, either. I believe you can memcpy() in
to an (unsigned char *) and back again. If sizeof(int) >= sizeof(void*)
you might be able to do the cast, but the use of the value of the
int is non-portable. Those writing large model x86 code, and
who try to do such casts, know all about this one.

>> cptr = C_PTR(p+1)

> I suppose you are trying to use a structure constructor here. You can't
> do that with C_PTR as it has (intentionally) private components. The
> whole point of private components is to keep you from fiddling with the
> innards. You can't write a structure constructor for a private component
> - you don't even know what the components are. Now maybe you know what a
> C pointer better look like inside, but accordingh to the Fortran
> compiler, you don't know.

From K&R2 (close, but not exactly, the C89 standard) A6.6:

"Certain other conversions involving pointers and integers are
permitted, but have implementation defined aspects. They must
be specified by an explicit type-conversion operator, or cast."

"A pointer may be converted to an integral type large enough to
hold it; the required size is implementation-dependent. The
mapping function is also implementation dependent."

"An object of integral type may be explicitly converted to a
pointer. The mapping always carries a sufficiently wide integer
converted from a pointer back to the same pointer, but is
otherwise implementation-dependent."

>>bug1.f90:10: internal compiler error: Segmentation fault

> Well, of course, you know teh usual commentary about internal compiler
> errors anyway.

-- glen

Craig Powers

unread,
Oct 15, 2007, 4:40:36 PM10/15/07
to
glen herrmannsfeldt wrote:
> If sizeof(int) >= sizeof(void*)
> you might be able to do the cast, but the use of the value of the
> int is non-portable.

Whether that's an issue or not depends on your purpose in casting in the
first place. One usage I've made of casting into an int (in C++, rather
than C, but the issues are the same) was to store the value in an array
of other characteristics which were int. Then, all I wanted to do was
cast to and then back from an int. (I could have and probably should
have stored an array of POD structs instead, and foregone the
typecasting, I don't remember why I did it the way I did it.)

James Van Buskirk

unread,
Oct 15, 2007, 4:53:34 PM10/15/07
to
"Craig Powers" <eni...@hal-pc.org> wrote in message
news:4713d044$0$63178$a726...@news.hal-pc.org...

I believe that GH intentionally indroduces disinformation as it's
simply impossible for anyone to make posts as stupid as he does.
If you examine my original code you will see that pointers (and
handles elsewhere) are cast to INTEGER(C_INTPTR_T), which does
not have the problems that casting to INTEGER(C_INT) would. It's
just a waste of time for me to try to correct this flood of dis-
information when he can simply pile another flood on top of my
corrections, so I usually don't bother to even read his posts.
That should not lead you to believe that he has ever made a
followup to one of my posts that doesn't need correcting, just
that I have concluded that it's mostly futile anyhow.

glen herrmannsfeldt

unread,
Oct 15, 2007, 8:07:09 PM10/15/07
to
Craig Powers wrote:
> glen herrmannsfeldt wrote:

>> If sizeof(int) >= sizeof(void*)
>> you might be able to do the cast, but the use of the value of the
>> int is non-portable.

> Whether that's an issue or not depends on your purpose in casting in the
> first place. One usage I've made of casting into an int (in C++, rather
> than C, but the issues are the same) was to store the value in an array
> of other characteristics which were int. Then, all I wanted to do was
> cast to and then back from an int.

In that case, assuming the int is large enough, it is supposed to work.

There are those who try to do arithmetic on an int, cast from a C
pointer, and that is non-portable.

In my previous post I quoted from K&R2, which is based on a draft of
the C89 standard.

-- glen

Wade Ward

unread,
Oct 17, 2007, 5:19:49 AM10/17/07
to


"James Van Buskirk" <not_...@comcast.net> wrote in message
news:ltGdnVzewbrSTo7a...@comcast.com...

Ovvero, per esempio, se
void* pippo;
long pluto;

Puoi assegnare pluto a pippo, ma con un recast di pluto:
pippo=(void*)pluto;


> "A pointer may be converted to an integral type large enough to
> hold it; the required size is implementation-dependent. The
> mapping function is also implementation dependent."
>

Ovvero, puoi assegnare il valore di un pointer ad una variabile
pluto=(long)pippo;

ma la variabile deve potere contenere il valore del pointer: se il
pointer e' un 32bit, occore
usare un tipo da 32 bit almeno... questo dipende dall' architettura del
processore.
Su un processore a 16bit, con 16bit di indirizzamento, un pointer e' un
16bit e basta un int.
Su processore a 32bit con 32bit di indirizzo ci vuole un tipo da 32bit
(di solito ma non
necessariamente, un long: basterebbe un int ma su alcuni 32bit, gli int
possono essere a 16bit..)

> "An object of integral type may be explicitly converted to a
> pointer. The mapping always carries a sufficiently wide integer
> converted from a pointer back to the same pointer, but is
> otherwise implementation-dependent."
>
>

Vedi sopra; Puoi assegnare pluto a pippo, ma con un recast e pluto deve
avere la stessa dimensione
fisica di pippo (se pippo e' 32bit, pluto deve essere almeno da 32bit,
salvo casi particolari ;-) )
pippo=(void*)pluto;
>
Può qualcuno che conosca questo soggetto commentare il suddetto?


A questo uno potrebbe chiedersi il perche' di tutte queste cose....
In realta' lo scambio interi/pointers ha solo alcune applicazioni
abbastanza particolari e non dovrebbe essere abusato.
Quella che mi viene in mente e' la gestione di hardware, con mappe
di indirizzi espresse in valori interi che poi vengono assegnate
a puntatori...
Ad ogni modo, queste operazioni sono molto legare al tipo di architettura
della CPU, alla dimensione dei tipi e quindi *poco* portabili, per cui.....

My Italian's a little weak, but I like Glen in every language.
--
wade ward
"Nicht verzagen, Bruder Grinde fragen."


0 new messages