{"id":497,"date":"2014-07-22T21:50:32","date_gmt":"2014-07-22T20:50:32","guid":{"rendered":"http:\/\/numbercrunch.de\/blog\/?p=497"},"modified":"2023-01-18T22:40:51","modified_gmt":"2023-01-18T21:40:51","slug":"lost-in-translation","status":"publish","type":"post","link":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/","title":{"rendered":"Lost in translation"},"content":{"rendered":"<p>Recently I found myself unexpectedly lost in translation.\u00a0 As a \u201cnative speaker\u201d of several languages of the C family I was facing the problem of calling various functions of a FORTRAN library from my C\/C++ program. Although, I had done such kind of mixed-language programming in the past this time something went seriously wrong.\u00a0 To call a FORTRAN function from C\/C++ one has to provide a C\/C++ function prototype for each FORTRAN function.\u00a0 Thus the one-million dollar question was how does, for example, the FORTRAN function declaration<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">      DOUBLE COMPLEX FUNCTION ZDOTC(N, ZX, INCX, ZY, INCY)\n*     .. Scalar Arguments ..\n      INTEGER INCX, INCY, N\n*     .. Array Arguments ..\n      DOUBLE COMPLEX ZX(*), ZY(*)\n<\/pre>\n<p style=\"text-align: justify;\">translate to a C\/C++ function prototype?\u00a0 (This BLAS function calculates the scalar product of two complex vectors.)<\/p>\n<p style=\"text-align: justify;\">Though there is no standard that defines inter-language operability between C\/C++ and FORTRAN the answer is: It depends.\u00a0 It depends on the employed FORTRAN and C\/C++ compilers and possibly on the operating system.<\/p>\n<p style=\"text-align: justify;\">First, one has to figure out which C\/C++ data types are binary compatible to the various FORTRAN data types.\u00a0 As mentioned before this is a compiler-dependent issue.\u00a0 Typically the following mapping applies<\/p>\n<ul>\n<li><code>INTEGER<\/code> -&gt; <code>signed int<\/code><\/li>\n<li><code>REAL<\/code> -&gt; <code>float<\/code><\/li>\n<li><code>DOUBLE PRECISION<\/code> -&gt; <code>double<\/code><\/li>\n<li><code>COMPLEX<\/code> -&gt; <code>struct { float z[2]; }<\/code> or <code>float complex<\/code> (with C99 and header file <code>complex.h<\/code>) or <code>std::complex&lt;float&gt;<\/code> (in C++ with header file <code>complex<\/code>)<\/li>\n<li><code>DOUBLE COMPLEX<\/code> -&gt; <code>struct { double z[2]; }<\/code> or <code>double complex<\/code> (with C99 and header file <code>complex.h<\/code>) or <code>std::complex&lt;double&gt;<\/code> (in C++ with header file <code>complex<\/code>)<\/li>\n<li><code>LOGICAL<\/code> -&gt; <code>int<\/code> (Only specific values may be valid representations of\u00a0 true and false.)<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Secondly, the FORTRAN function&#8217;s name in C\/C++ representation has to be determined.\u00a0 Again there is no general rule.\u00a0 Most compilers, however, down-case the FORTRAN function name and add one or two underscores. Furthermore, FORTRAN function arguments are usually passed by pointers. Thus, the C++ function prototype for the <code>ZDOTC<\/code> FORTRAN function shown above may be<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">extern \"C\" {\n  std::complex&lt;double&gt; zdotc_(const int *n,\n                              const std::complex&lt;double&gt; *zx, const int *incx,\n                              const std::complex&lt;double&gt; *zy, const int *incy);\n}\n<\/pre>\n<p style=\"text-align: justify;\">The <code>ZDOTC<\/code> function does not modify all its input parameters (so-called in-parameters).\u00a0 Therefore, the pointers in the C++ prototype have been declared as const.\u00a0 For parameters that may be modified by a FORTRAN function (so-called in-out-parameters) the corresponding C\/C++ pointers have to be declared as non-const.<\/p>\n<p style=\"text-align: justify;\">With the explanations given, the translation form the FORTRAN function declaration to the C++ function prototype of <code>ZDOTC<\/code> looks straight forward.\u00a0 Some FORTRAN compilers, however, do something quite unexpected, which finally let me feel a little bit lost in translation after getting strange run-time errors when calling<code> ZDOTC<\/code> from C++ as illustrated above.<\/p>\n<p>Some FORTRAN compilers, in particular g77 and ifort, generate code that requires special treatment for complex return values.\u00a0 These are returned via an extra argument in the calling sequence that points to where to store the return value.\u00a0 Thus, the C++ function becomes<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"cpp\">extern \"C\" {\n  void zdotc_(std::complex&lt;double&gt; *res, const int *n,\n              const std::complex&lt;double&gt; *zx, const int *incx,\n              const std::complex&lt;double&gt; *zy, const int *incy);\n}\n<\/pre>\n<p>with possibly a second underscore in the function name.<\/p>\n<p style=\"text-align: justify;\">All these different calling conventions make it hard to write portable C\/C++ programs that interact with FORTRAN libraries.\u00a0 Some FORTRAN compilers even allow to specify on compile-time how to deal with complex return values or to change the byte-width of INTEGER and REAL variables.\u00a0 This has to be taken into account when specifying the C\/C++ function prototypes of FORTRAN functions.<\/p>\n<p>Further reading:<\/p>\n<ul>\n<li><a href=\"https:\/\/gcc.gnu.org\/onlinedocs\/gcc-4.8.0\/gfortran\/Mixed_002dLanguage-Programming.html\">GCC mixed language programming<\/a><\/li>\n<li><a href=\"https:\/\/software.intel.com\/en-us\/node\/510841\">Intel FORTRAN mixed language programming<\/a><\/li>\n<li><a href=\"&quot;http:\/\/www-zeus.desy.de\/~burow\/cfortran\/\">cfortran.h : Interfacing C or C++ and FORTRAN<\/a><\/li>\n<li><a href=\"&quot;http:\/\/arnholm.org\/software\/cppf77\/cppf77.htm\">Mixed language programming using C++ and FORTRAN 77<\/a><\/li>\n<li><a href=\"&quot;http:\/\/www2.astro.indiana.edu\/~jthorn\/c2f.html\">Calling Fortran Subroutines from C\/C++<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Recently I found myself unexpectedly lost in translation.\u00a0 As a \u201cnative speaker\u201d of several languages of the C family I was facing the problem of calling various functions of a FORTRAN library from my C\/C++ program. Although, I had done such kind of mixed-language programming in the past this time something went seriously wrong.\u00a0 To&hellip; <a href=\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Lost in translation<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-497","post","type-post","status-publish","format-standard","hentry","category-software"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Lost in translation - Number Crunch<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Lost in translation - Number Crunch\" \/>\n<meta property=\"og:description\" content=\"Recently I found myself unexpectedly lost in translation.\u00a0 As a \u201cnative speaker\u201d of several languages of the C family I was facing the problem of calling various functions of a FORTRAN library from my C\/C++ program. Although, I had done such kind of mixed-language programming in the past this time something went seriously wrong.\u00a0 To&hellip; Continue reading Lost in translation\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\" \/>\n<meta property=\"og:site_name\" content=\"Number Crunch\" \/>\n<meta property=\"article:published_time\" content=\"2014-07-22T20:50:32+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-01-18T21:40:51+00:00\" \/>\n<meta name=\"author\" content=\"Heiko Bauke\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Heiko Bauke\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\"},\"author\":{\"name\":\"Heiko Bauke\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"headline\":\"Lost in translation\",\"datePublished\":\"2014-07-22T20:50:32+00:00\",\"dateModified\":\"2023-01-18T21:40:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\"},\"wordCount\":525,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"articleSection\":[\"Software\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\",\"name\":\"Lost in translation - Number Crunch\",\"isPartOf\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\"},\"datePublished\":\"2014-07-22T20:50:32+00:00\",\"dateModified\":\"2023-01-18T21:40:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.numbercrunch.de\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Lost in translation\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#website\",\"url\":\"https:\/\/www.numbercrunch.de\/blog\/\",\"name\":\"Number Crunch\",\"description\":\"A computational science blog.\",\"publisher\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413\",\"name\":\"Heiko Bauke\",\"logo\":{\"@id\":\"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Lost in translation - Number Crunch","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/","og_locale":"en_US","og_type":"article","og_title":"Lost in translation - Number Crunch","og_description":"Recently I found myself unexpectedly lost in translation.\u00a0 As a \u201cnative speaker\u201d of several languages of the C family I was facing the problem of calling various functions of a FORTRAN library from my C\/C++ program. Although, I had done such kind of mixed-language programming in the past this time something went seriously wrong.\u00a0 To&hellip; Continue reading Lost in translation","og_url":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/","og_site_name":"Number Crunch","article_published_time":"2014-07-22T20:50:32+00:00","article_modified_time":"2023-01-18T21:40:51+00:00","author":"Heiko Bauke","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Heiko Bauke","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#article","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/"},"author":{"name":"Heiko Bauke","@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"headline":"Lost in translation","datePublished":"2014-07-22T20:50:32+00:00","dateModified":"2023-01-18T21:40:51+00:00","mainEntityOfPage":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/"},"wordCount":525,"commentCount":2,"publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"articleSection":["Software"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/","url":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/","name":"Lost in translation - Number Crunch","isPartOf":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#website"},"datePublished":"2014-07-22T20:50:32+00:00","dateModified":"2023-01-18T21:40:51+00:00","breadcrumb":{"@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.numbercrunch.de\/blog\/2014\/07\/lost-in-translation\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.numbercrunch.de\/blog\/"},{"@type":"ListItem","position":2,"name":"Lost in translation"}]},{"@type":"WebSite","@id":"https:\/\/www.numbercrunch.de\/blog\/#website","url":"https:\/\/www.numbercrunch.de\/blog\/","name":"Number Crunch","description":"A computational science blog.","publisher":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.numbercrunch.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/e73eab65b1721dd0c3d408edb887e413","name":"Heiko Bauke","logo":{"@id":"https:\/\/www.numbercrunch.de\/blog\/#\/schema\/person\/image\/"}}]}},"_links":{"self":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/497"}],"collection":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/comments?post=497"}],"version-history":[{"count":11,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/497\/revisions"}],"predecessor-version":[{"id":982,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/posts\/497\/revisions\/982"}],"wp:attachment":[{"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/media?parent=497"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/categories?post=497"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.numbercrunch.de\/blog\/wp-json\/wp\/v2\/tags?post=497"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}