Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

343
Vistas
gfortran: pasa el argumento lógico a la función Fortran desde C

¿Qué tipo de argumento debo usar en C al llamar a una función Fortran que toma argumentos logical , específicamente con gfortran? ¿Dónde está documentado esto para gfortran?

Aquí hay un programa de ejemplo que no se compila sin advertencias:

Contenido de one.f :

 subroutine proc1(x) logical x end

Contenido de main.c :

 void proc1_(_Bool *x); int main() { _Bool x; proc1_(&x); return 0; }

Si compilo usando GCC de la siguiente manera, con LTO habilitado, recibo una advertencia sobre prototipos de funciones que no coinciden:

 gfortran -flto -c one.f gcc -flto -c main.c gcc -flto main.o one.o

La advertencia que recibo:

 main.c:2:6: warning: type of 'proc1_' does not match original declaration [-Wlto-type-mismatch] 2 | void proc1_(_Bool *x); | ^ one.f:2:22: note: 'proc1' was previously declared here 2 | subroutine proc1(x) | ^ one.f:2:22: note: code may be misoptimized unless '-fno-strict-aliasing' is used

Tenga en cuenta que habilitar LTO le permite al enlazador verificar que los tipos de argumentos coincidan entre prototipos. Desafortunadamente, usar LTO no es nuestra elección. CRAN requiere que el código enviado se compile sin estas advertencias con LTO habilitado.

Solo veo problemas cuando trato de usar argumentos logical . real , integer y character están todos bien.

Se le puede pedir a gfortran que produzca prototipos en C, y este es el resultado que me da:

 gfortran -flto -fc-prototypes-external -c one.f
 void proc1_ (int_fast32_t *x);

Usar int_fast32_t en el prototipo C tampoco funciona. Ningún tipo que probé lo hizo, ni int , ni _Bool . Por lo general, cuando hay una discrepancia de tipos entre los prototipos, el mensaje de error menciona cuál debería ser el tipo, pero no en este caso.

¿Cómo puedo encontrar cuál es el tipo correcto para usar?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Para una interoperabilidad C-Fortran realmente moderna, debe usar los tipos (tipos) proporcionados por el módulo iso_c_binding y hacer que su procedimiento Fortran se bind(c) . De esa manera puedes usar logical(c_bool) .

Al estilo antiguo, lo mejor es trabajar con enteros y pasar un int y solo corregir de integer a logical dentro de Fortran. La antigua C no tenía ningún bool , se agregó más tarde.

Con cambios mínimos:

 subroutine proc1(x) use iso_c_binding logical(c_bool) x end
 #include <stdbool.h> void proc1_(bool *x); int main() { bool x; proc1_(&x); return 0; }
 > gfortran -flto -c one.f > gcc -flto -c main.c > gcc -flto main.o one.o

no emite ninguna advertencia en mi Linux y GCC 7 y 10.

O después de más cambios:

 subroutine proc1(x) bind(C, name="proc1") use iso_c_binding logical(c_bool), value :: x end
 #include <stdbool.h> void proc1(bool x); int main() { bool x; proc1(x); return 0; }

El cambio a pasar por valor, por supuesto, solo cuando de hecho es solo un parámetro de entrada.

over 4 years ago · Santiago Trujillo Denunciar

0

La solución portátil correcta y garantizada es, como se explica en la respuesta de Vladimir F, crear una rutina de envoltura Fortran que use ISO_C_BINDING. Este contenedor también puede aprovechar la oportunidad para hacer una interfaz C más idiomática, por ejemplo, usando el especificador de value para pasar escalares por valor.

Sin embargo, para la solución rápida y sucia que funciona en GFortran SIN LTO (y algo probable en otros compiladores, pero no hay garantías), consulte https://gcc.gnu.org/onlinedocs/gfortran/Internal-representation-of-LOGICAL- variables.html#Representación-interna-de-variables-LOGICAS . Es decir, puede pasar una variable entera de C del tamaño apropiado que contenga 1 para verdadero y 0 para falso. Tamaño apropiado aquí, lo que significa que, a menos que haya compilado su código Fortran con -fdefault-integer-8 o tales opciones de compilación, el tipo lógico predeterminado de GFortran será de 4 bytes, por lo que un C int simple debería ser bueno (o int32_t si realmente desea asegúrese, aunque no creo que GFortran admita ningún objetivo en el que C int no sea de 32 bits).

La razón por la que esto no funciona con LTO es que, si bien lo anterior funciona, en las entrañas de GCC, las variables LÓGICAS de Fortran son casi las mismas que los números enteros, pero no del todo. Entonces, en la práctica, son variables enteras especiales con un valor máximo de 1 y un valor mínimo de 0, aunque ocupan más espacio (según lo especificado por su tipo de parámetro). Por lo tanto, es probable que este tipo de discrepancia de tipo sea de lo que se queja. Desafortunadamente, no hay solución para esta, excepto la solución correcta anterior a través de ISO_C_BINDING.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda