contents   index   previous   next



Name-mangling

 

Anyone with a little mixed language programming experience has at one point or another encountered an error that looks similar to this:

 

D2.OBJ : error LNK2001: unresolved external symbol "MessageBeep"

 

This type of error is generated by the linker, and is telling you that it cannot find a procedure that is called from the program you are linking. Those of you that have done a fair amount of mixed-language programming are likely very familiar with this error. The way it works is as follows:

 

Let's say you have source for a C procedure called MYPROC in the file the A.C. Furthermore, in the OBJ file generated from A.C, the procedure appears with the name MYPROC. In linker jargon, the name MYPROC is a public symbol residing in A.OBJ. Now, let's say you want to call procedure MYPROC from another creatively named source file like B.f90. When you call MYPROC from B.f90, the compiler does not know where the real code for MYPROC resides. In this situation the compiler emits a record in B.OBJ. This record tells the linker it needs to fix up the call to procedure MYPROC with MYPROC 's real address. This record is called an external symbol definition since the location of MYPROC is external to the source module that called it. One of the linker's primary jobs is to match up or "resolve" external definitions (like B.OBJ has for the symbol MYPROC) with public symbols (like that contained in A.OBJ).

 

In this example, what's ultimately important to the linker is not what you call the function in your source files. Rather, the only thing that matters is that the names of the public and external names match exactly. If they don't match exactly, you get the dreaded "unresolved external" linker error. Of course, good programmers that we are, we have been careful to make sure that MYPROC is spelled exactly the same and with the same arguments in both the source file for the procedure (A.C) and the calling program (B.f90). The problem is that compilers have a mind of their own, and usually change symbol names behind your back. For example, some C compilers prefix an underscore to the symbol name as it appears in the OBJ file. Thus, procedure MYPROC in A.C appears as the public symbol _MYPROC in A.OBJ. Another example comes from C++; the compiler takes the function name and adds additional information about the function's parameters. In Visual C++, the function void MYPROC (int I) becomes ?MYPROC@@YAXH@Z. Your Fortran program will never find these public symbols unless you have a way to tell it how the C compiler has renamed them.

 

The renaming of procedures performed by the compiler is called mangling or decorating, and allows the linker to differentiate between overloaded functions, defined variables and internal or intrinsic procedures. Name mangling is usually not an issue when working in code that is compiled with the same compiler (for example, if all your source files are in Fortran and you use the same Fortran compiler on all of them). However, it becomes a major consideration when you are working with mixed languages, or even with the same language but different brands of compilers.

 

Name mangling is compiler-specific. There are no rules in this area. By default, most Fortran compilers convert procedure names to upper case, but not even this is true for all compilers. Absoft Pro Fortran and Digital Visual Fortran mangle names by prefixing an underscore "_" character and suffixing @nn, where nn is the size of the calling stack, when a procedure is declared to use the STDCALL convention. Lahey Fortran 95 lets you indicate the name of the exported procedure as you want it to appear in the DLL.

 

Dealing with name-mangling