according to ISO/IEC SC22/JTC1/WG5/N1581, C1237a (R1225) one
is not allowed to use BIND on an internal subroutine.
ftp://ftp.nag.co.uk/sc22wg5/N1551-N1600/N1581.pdf
page 14. I did not understand too well the note below this
"C1237a (R1225) A proc-language-binding-spec shall not be
specified for a procedure defined in a sub-
module unless its interface is declared in the ancestor module."
Ok. Will do the above, but my question is: Why, and is there a
way to go around it?
Because it makes it much easier if I can write the subroutine inside
CONTAINS rather than outside, where now I have to provide an interface
for the subroutine, and also the subroutine needs an extra USE to access
the fortran openGL. It it was an internal sub, then the program USE
will be enough. Now I have to duplicate USE openGL in the main
program and in the subroutine.
It is a routine that will _only_ be called by this one main program.
I just think it fits more logically as an internal subroutine, but
I can't do that due to the BIND on it per the fortran OPEN GL spec.
Here is the program when the subroutine is internal (I am
writing small fortran programs using the fortran openGL interface
to learn it)
---------------------------------------
PROGRAM simple1
USE opengl_glut
USE opengl_gl
IMPLICIT none
CALL glutInit()
......
CALL glutDisplayFunc(display) !-- callback to draw
CALL glutMainLoop
CONTAINS
SUBROUTINE display() bind(c)
implicit none
CALL glClear(GL_COLOR_BUFFER_BIT)
.....
CALL glFlush()
END SUBROUTINE display
END PROGRAM simple1
-----------------------------------
And here is how it would look like with the subroutine outside:
------------------------------
SUBROUTINE display() bind(c)
USE opengl_gl
implicit none
CALL glClear(GL_COLOR_BUFFER_BIT)
.....
CALL glFlush()
END SUBROUTINE display
PROGRAM simple1
USE opengl_glut
USE opengl_gl
IMPLICIT none
interface
subroutine display() bind(c)
end subroutine display
end interface
CALL glutInit()
......
CALL glutDisplayFunc(display) !-- callback to draw
CALL glutMainLoop
END PROGRAM simple1
---------------------------
You can see, as internal subroutine, the program is smaller
in size and less code duplication.
I am just asking to learn, not to complain, I am a newbie
in fortran. I am sure there is a good reason for this.
thanks,
--Nasser
|
|
0
|
|
|
|
Reply
|
Nasser
|
7/22/2012 6:10:19 AM |
|
Nasser M. Abbasi wrote:
>
> according to ISO/IEC SC22/JTC1/WG5/N1581, C1237a (R1225) one
> is not allowed to use BIND on an internal subroutine.
> ftp://ftp.nag.co.uk/sc22wg5/N1551-N1600/N1581.pdf
Instead of looking at the draft Technical Report for Enhanced Module
Facilities in Fortran, I'd recommend the Fortran 95/2003/2008 standards.
See http://www.nag.co.uk/sc22wg5/links.html and
http://gcc.gnu.org/wiki/GFortranStandards
Actually, your program below seems to be a valid Fortran 2008 program,
but not a valid Fortran 2003 program. Note that "display" has no C
binding name � and Fortran 2003 also doesn't allow one:
"C1254 (R1229) A proc-language-binding-spec with a NAME= specifier shall
not be specified in the function-stmt or subroutine-stmt of an internal
procedure, or of an interface body for an abstract interface or a dummy
procedure."
Fortran 2003 had:
"C1237 (R1225) A proc-language-binding-spec shall not be specified for
an internal procedure."
Thus, depending on compilers you use, your could actually consider to
use this Fortran 2008 feature.
[gfortran 4.3 supports Bind(C) on internal procedures as vendor
extension and starting from 4.4 as F2008 extension (with proper
-std=f2003/f2008 diagnostic).]
The reason that C binding was now allowed for internal procedures is the
same as why passing any internal procedures as actual argument was not
supported: One has to be careful regarding host-associated variable. For
instance the following program, which should print 5 2. Here, the
variable "j" of the first call to "foo" has to be used by "internal" �
and not the one of the second call to "foo".
Implementing this properly is not trivial, hence, it took a while until
the Fortran committee finally allowed it (in Fortran 2008). (gfortran
supports it since GCC 4.6; as the compiler itself supported it, it was
one of the simplest features to implement.)
program test
call foo(1, .false.)
end program test
subroutine bar(f)
procedure() :: f
call foo(5, .true.)
call f()
end subroutine bar
subroutine foo(i, print)
logical :: print
integer :: j
j = 2*i
if (print) then
print *, i
else
call bar(internal)
end if
contains
subroutine internal()
print *, j
end subroutine internal
end
Tobias
> ---------------------------------------
> PROGRAM simple1
> USE opengl_glut
> USE opengl_gl
> IMPLICIT none
>
> CALL glutInit()
> .....
> CALL glutDisplayFunc(display) !-- callback to draw
> CALL glutMainLoop
>
> CONTAINS
> SUBROUTINE display() bind(c)
> implicit none
>
> CALL glClear(GL_COLOR_BUFFER_BIT)
> .....
> CALL glFlush()
> END SUBROUTINE display
>
> END PROGRAM simple1
> -----------------------------------
|
|
0
|
|
|
|
Reply
|
burnus (564)
|
7/22/2012 7:42:13 AM
|
|
On 7/22/2012 2:42 AM, Tobias Burnus wrote:
>
> Actually, your program below seems to be a valid Fortran 2008 program,
> but not a valid Fortran 2003 program. Note that "display" has no C
> binding name � and Fortran 2003 also doesn't allow one
Thanks Tobias, That really helped. I did not think of trying f2008
since I am using an openGL fortran 2003 binding and was using f2003
all the time.
You are correct! It worked with f2008. I changed the code to use
an internal subroutine with bind(c) and it compiled and runs fine
now.
I'll use f2008 from now on.
Fyi, here is a complete small program to draw a line on the screen
with the compile command I use. Using version 4.6.3 on Linux 32 bit
-------------------------------
PROGRAM simple3 !-- use F2003 Fortran openGL
USE opengl_glut
USE opengl_gl
IMPLICIT none
integer :: i
CALL glutInit()
CALL glutInitDisplayMode(GLUT_SINGLE+GLUT_RGB)
CALL glutInitWindowSize( 250, 250 );
CALL glutInitWindowPosition( 200, 200 );
i = glutCreateWindow( " simple1 " );
CALL glClearColor(0.,0.,0.,0.) !-- background color
CALL glMatrixMode(GL_PROJECTION)
CALL glLoadIdentity()
CALL glOrtho(0.0d0,1.0d0,0.0d0,1.0d0,-1.0d0,1.0d0)
CALL glutDisplayFunc(display) !-- callback to draw
CALL glutMainLoop
CONTAINS
!-------------------
SUBROUTINE display() bind(c)
implicit none
CALL glClear(GL_COLOR_BUFFER_BIT)
CALL glColor3f(1.0,1.0,1.0)
call glBegin(GL_LINES);
call glVertex3f(0.25, 0.25, 0.0)
call glVertex3f(0.75, 0.75, 0.0)
call glEnd( );
CALL glFlush()
END SUBROUTINE display
END PROGRAM simple3
-----------------------------
command to build:
gfortran -std=f2008 -Wall simple3.f90 GLUT_fonts.o OpenGL_freeglut.o
OpenGL_glu.o OpenGL_gl.o -L/usr/lib -lglut -lGL -lGLU -lXaw -lXt
-lXmu -lXi -lXext -lX11 -lm -lpthread -ldl -lgfortran -o simple3
../simple3
Thanks for your help. Much better using internal subroutine. Less
code to write and more clear.
--Nasser
|
|
0
|
|
|
|
Reply
|
Nasser
|
7/22/2012 8:43:13 AM
|
|
Nasser M. Abbasi <nma@12000.org> wrote:
> according to ISO/IEC SC22/JTC1/WG5/N1581, C1237a (R1225) one
> is not allowed to use BIND on an internal subroutine.
> ftp://ftp.nag.co.uk/sc22wg5/N1551-N1600/N1581.pdf
> page 14. I did not understand too well the note below this
(snip)
> Ok. Will do the above, but my question is: Why, and is there a
> way to go around it?
I believe this went away in Fortran 2008. If you are lucky enough
to have a F2003 compiler, you still might not have an F2008 compiler.
Note that, unless I remember it wrong, in F2003 you can't use
internal procedure names as actual arguments, BIND(C) or not.
If you can't use them without BIND(C), it is even less likely
with BIND(C). There is no way to call an internal procedure from C,
other than passing it, or a pointer to it, to an extenal routine.
I believe that both restrictions are gone in F2008.
Does that help? The way around is to find an F2008 compiler.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12254)
|
7/22/2012 9:22:20 AM
|
|
"Nasser M. Abbasi" <nma@12000.org> wrote in message
news:jug5ga$r06$1@speranza.aioe.org...
> And here is how it would look like with the subroutine outside:
> ------------------------------
> SUBROUTINE display() bind(c)
> USE opengl_gl
> implicit none
> CALL glClear(GL_COLOR_BUFFER_BIT)
> .....
> CALL glFlush()
> END SUBROUTINE display
> PROGRAM simple1
> USE opengl_glut
> USE opengl_gl
> IMPLICIT none
> interface
> subroutine display() bind(c)
> end subroutine display
> end interface
> CALL glutInit()
> .....
> CALL glutDisplayFunc(display) !-- callback to draw
> CALL glutMainLoop
> END PROGRAM simple1
Since Fortran 90, it's much more normal to put everything in modules.
Thus the normal code would be:
module OpenGL_stuff
USE opengl_gl
implicit none
contains
SUBROUTINE display() bind(c)
CALL glClear(GL_COLOR_BUFFER_BIT)
.....
CALL glFlush()
END SUBROUTINE display
end module OpenGL_stuff
PROGRAM simple1
USE opengl_glut
USE opengl_gl
USE OpenGL_stuff
IMPLICIT none
CALL glutInit()
.....
CALL glutDisplayFunc(display) !-- callback to draw
CALL glutMainLoop
END PROGRAM simple1
Also glut is so limiting that you will grow out of it quickly.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
|
|
0
|
|
|
|
Reply
|
not_valid (1681)
|
7/22/2012 12:08:46 PM
|
|
Nasser M. Abbasi <nma@12000.org> wrote:
> page 14. I did not understand too well the note below this
>
> "C1237a (R1225) A proc-language-binding-spec shall not be
> specified for a procedure defined in a sub-
> module unless its interface is declared in the ancestor module."
>
> Ok. Will do the above, but my question is: Why, and is there a
> way to go around it?
Others answered the other parts of your post as well or better than I
would. But I didn't notice any response to the above.
First, note that nothing else in your posting had anything to do wih
submodules. I will take the above as an unrelated question that happened
tp occur to you. If you did think there was a relationship, then realize
that there is not; since the code you showed has no submodules, a
restriction related to what you can do in a submodule is moot.
But answering the question, I would guess (I don't recall discussion of
that particular restriction, but I think I can see why it would exist)
that this relates to the fact that a submodule is in essence an
implementation of what is described in the ancestor module. I might even
have preferred a term like "implementation module" as more descriptive
than "submodule". A proc-language-binding-spec makes a procedure
"visible" outside of the module. A submodule is not supposed to have
externally visible bits that are other than what was declared in its
ancestor module. If it had such things, that would make it more than an
implementation of what was already described. Anyway, that's what I'd
guess.
--
Richard Maine
email: last name at domain . net
domain: summer-triangle
|
|
0
|
|
|
|
Reply
|
nospam47 (9742)
|
7/23/2012 8:48:30 AM
|
|
|
5 Replies
39 Views
(page loaded in 0.106 seconds)
Similiar Articles: Why can not I implicitly convert "Derived **" to "Base * const ...But why can not I implicitly ... Why the conversion from D* to B * const & is allowed? Yes. It is "Convert D * to B * and then bind to const ... const member function ... Down-cast a polymorphic pointer? - comp.lang.fortran... end if The ch => b does not seem to be allowed in ... and I violated the standard by not using TYPE, BIND ... base%cmethod = cmethod end subroutine where I've not ... const member functions in classes derived from templates. - comp ...Since GetSize() obviously is a "read-only" member function and does not change the internal ... This isn't usually allowed, though, so why assume it is because A is a ... Something bad happened to my gfortran installation - comp.lang ...I don't know whether the compiler is allowed to also consider procedures from ISO_C_BINDING to ... end function stmxcsr_template function fstsw_template() bind(C ... Bad use of stringstream temporary? - comp.lang.c++... non-const reference to a stream which will obviously not bind to ... object is non-const, a non-const member function is allowed to be called for it. That function can ... Static const integral data members can be initialized? - comp.lang ...No, you're not allowed to build an annex, because where ... try to take the address of such an object or bind it ... An object or non-overloaded function is used if its ... problem with mixed c and fortran code - comp.lang.fortran ...... message news:JmjAo.1296$MF5.294@viwinnwfe02.internal ... it is stop now and go and read about BIND(C), please understand why the text about CHARACTER(*) function ... HP-UX 11.x and Legato Networker 5.5 - comp.sys.hp.hpuxThe thing that makes this difficult is that I am not allowed ... so it seems to me it would be a system issue or internal ... for HP-UX clone1 B.11.23 - comp.sys.hp.hpux rpc-bind ... Modifying MEX arguments in place? - comp.soft-sys.matlab ...Do you know why it is not implemented in ... 0000 Of course you are not going to use an inplace mex function this ... only, in the sense that you're >> not allowed ... recvfrom returns with an error code of 14, EFAULT "Bad Address ...... toReturn, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0 || bind ... C++ is able to do this, but recv() is an ordinary C function, not a C++ function. Boost: bind.hpp documentation - Boost 1.47.0 - Boost C++ LibrariesUsing bind with function objects. bind is not limited to ... f, x, _1)(i); // (internal copy of x).f(i) bind(&X::f ... Implementations are allowed to provide additional bind ... pmuellr: bind() considered harmfulwhy does bind() not rock? gets in ... just allowed the use of a function parameter. The trick with bind() is that ... of the bound function for Web Inspector's internal ... 7/23/2012 3:38:57 PM
|