I'm newbie in C language... Just want to ask how to enable linking floating point library in TurboC?
From the comp.os.msdos.programmer FAQ:
"Floating point formats not linked" is
a Borland run-time error (Borland C or
C++, Turbo C or C++). Borland's
compilers try to be smart and not link
in the floating- point (f-p) library
unless you need it. Alas, they all get
the decision wrong. One common case is
where you don't call any f-p
functions, but you have %f or other
f-p formats in scanf() or printf()
calls. The cure is to call an f-p
function, or at least force one to be
present in the link.
To do that, define this function
somewhere in a source file but don't
call it:
static void forcefloat(float *p)
{
float f = *p;
forcefloat(&f);
}
It doesn't have to be in the module
with the main program, as long as it's
in a module that will be included in
the link.
Related
I have code that gives me an error. Implicit declaration of isNumericFloat.
I want to know if the function:
isNumericFloat()
a built it function in C?
NO, it's not a "built-in" c function.1
This function is used somewhere in your code and it's not part of the standard library. In fact, just because it uses camel case which is not very common in c code it seems like an odd function written by a not so c-ish programmer, of course that's a subjective reason, but commonly c programmers would choose is_numeric_float().
You need to search your code to see if you can find it's defintion, but in the mean time you can provide a prototype, like
int isNumericFloat(float value); // I don't really know what arguments it takes
// but you can surely infer them from the code
before it's ever called in the code, if you do so one of these two things will happen
If there is a definition for the function somewhere, it will compile fine.
If there is no definition, the linker will tell you that there is/are undefined reference/s to it in the code.
1Strictly speaking, there are no built-in functions in c, there is something called the standard library (headers starting with std , like stdlib.h), and I mean that it's not part of such library.
Suppose there's a list of arguments stored somehow, in a array for example.
Given a function pointer, how could I make a call to it passing the stored list of arguments?
I'm not trying to pass the array as an argument ok. You got it, ok? I want to pass each of its elements as an argument. An array is just to illustrate, I could be storing the arguments in some tuple structure. Also, look that I have at hand a function pointer and may have a signature in string format. I'm not trying to just define a function that is able to deal with a variadic list.
The only way I see how to do that is by employing assembly (by __asm push et al.) or this:
void (*f)(...);
int main()
{
f = <some function pointer>;
int args[]; <stored in a array, just to illustrate>
int num_args = <some value>;
switch(num_args)
{
case 0:
f();
break;
case 1:
f(args[0]);
break;
case 2:
f(args[0], args[1]);
break;
/* etc */
}
return 0;
}
I don't like this approach too much...
Is there another portable and shorter form?
Several script languages are able to call C functions.
How script languages like Python or Ruby do that? How they implement it in a portable way? Does they just use assembly for several platforms or the above in the end?
Look that I'm really not asking about details of parameter marshaling and other stuff from script languages to C, I'm interested only in how, in the end, internally, the call to the C function by the script language is built.
EDIT
I'll keep the question's title but I think a better way for asking it is:
How to call a C function with its pointer and signature available only at runtime?
UPDATE
From Foreign Interface for PLT Scheme:
A call-out is a normal function call. In a dynamic setting,
we create a “call-interface” object which specifies (binary)
input/output types; this object can be used with an arbitrary
function pointer and an array of input values to perform a callout to the function and retrieve its result. Doing this requires
manipulating the stack and knowing how a function is called,
these are details that libffi deals with.
Thanks #AnttiHaapala for searching, finding and pointing libffi. It's what I was looking for, it's being used by a bunch of script languages, it's a portable library, implemented across several architectures and compilers.
You asked what is the portable way to call any function pointer with given number of arguments. The correct answer is that there is no such way.
For example python is able to call C functions through the ctypes module, but this is portable only for as long as you know the exact prototype and calling conventions. In C the easiest way to achieve the same is to know the prototype of the function pointer at compile time.
Update
For python / ctypes example, on each platform that has the ctypes module enabled, python knows how to write the calling stack for a given set of arguments. On Windows for example, python knows of 2 standard calling conventions - cdecl with C order of parameters on stack, and stdcall with "pascal style ordering". On Linux it does need to worry about whether to call 32 or 64 bit shared objects, and so forth. If python is compiled to another platform, the ctypes needs changes as well; the C code in ctypes module is not, as such, portable.
Update 2
For Python the magic is in here: ctypes source code. Notably it seems to link http://sourceware.org/libffi/ which might be just what you needed.
I am the author of libffi. It will do what you are asking.
#AnttiHaapala pointed out libffi. Here's some information about it:
What is libffi?
Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. ‘libffi’ can be used in such programs to provide a bridge from the interpreter program to compiled code.
The ‘libffi’ library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time.
FFI stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The ‘libffi’ library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above ‘libffi’ that handles type conversions for values passed between the two languages.
‘libffi’ assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function.
Historic background
libffi, originally developed by Anthony Green (SO user: anthony-green), was inspired by the Gencall library from Silicon Graphics. Gencall was developed by Gianni Mariani, then employed by SGI, for the purpose of allowing calls to functions by address and creating a call frame for the particular calling convention. Anthony Green refined the idea and extended it to other architectures and calling conventions and open sourcing libffi.
Calling pow with libffi
#include <stdio.h>
#include <math.h>
#include <ffi.h>
int main()
{
ffi_cif call_interface;
ffi_type *ret_type;
ffi_type *arg_types[2];
/* pow signature */
ret_type = &ffi_type_double;
arg_types[0] = &ffi_type_double;
arg_types[1] = &ffi_type_double;
/* prepare pow function call interface */
if (ffi_prep_cif(&call_interface, FFI_DEFAULT_ABI, 2, ret_type, arg_types) == FFI_OK)
{
void *arg_values[2];
double x, y, z;
/* z stores the return */
z = 0;
/* arg_values elements point to actual arguments */
arg_values[0] = &x;
arg_values[1] = &y;
x = 2;
y = 3;
/* call pow */
ffi_call(&call_interface, FFI_FN(pow), &z, arg_values);
/* 2^3=8 */
printf("%.0f^%.0f=%.0f\n", x, y, z);
}
return 0;
}
I think I can assert libffi is a portable way to do what I asked, contrary to Antti Haapala's assertion that there isn't such a way. If we can't call libffi a portable technology, given how far it's ported/implemented across compilers and architectures, and which interface complies with C standard, we too can't call C, or anything, portable.
Information and history extracted from:
https://github.com/atgreen/libffi/blob/master/doc/libffi.info
http://en.wikipedia.org/wiki/Libffi
For safety you should unpack the variables before they are sent. Using assembler to hack the parameter stack might not be portable between compilers. Calling conventions might vary.
I can't speak for Ruby, but I have written quite a few programs using the C interfaces to Perl and Python. Perl and Python variables are not directly comparible with C variables, they have many more features. For example, a Perl scalar might have dual string and numeric values, only one of which is valid at any one time.
Conversion between Perl/Python variables and C is done using pack and unpack (in the struct module in Python). At the C interface you have to call specific APIs to do the conversion, depending on type. So, it is not just a straight pointer transfer, and it certainly does not involve assembler.
I generated a hash function with gperf couple of days ago. What I saw for the hash function was alien to me. It was something like this (I don't remember the exact syntax) :
unsigned int
hash(str, size)
register char* str;
register unsigned int size;
{
//Definition
}
Now, when I tried to compile with a C++ compiler (g++) it threw errors at me for not having str and size declared. But this compiled on the C compiler (gcc). So, questions:
I thought C++ was a superset of C. If its so, this should compile with a C++ compiler as well right?
How does the C compiler understand the definition? str and size are undeclared when they first appear.
What is the purpose of declaring str and size after function signature but before function body rather than following the normal approach of doing it in either of the two places?
How do I get this function to compile on g++ so I can use it in my C++ code? Or should I try generating C++ code from gperf? Is that possible?
1. C++ is not a superset, although this is not standard C either.
2/3. This is a K&R function declaration. See What are the major differences between ANSI C and K&R C?
.
4. gperf does in fact have an option, -L, to specify the language. You can just use -L C++ to use C++.
The Old C syntax for the declaration of a function's formal arguments is still supported by some compilers.
For example
int func (x)
int x
{
}
is old style (K&R style) syntax for defining a function.
I thought C++ was a superset of C. If its so, this should compile with a C++ compiler as well right?
Nopes! C++ is not a superset of C. This style(syntax) of function declaration/definition was once a part of C but has never been a part of C++. So it shouldn't compile with a C++ compiler.
This appears to be "old-school" C code. Declaring the types of the parameters outside of the parentheses but before the open curl-brace of the code block is a relic of the early days of C programming (I'm not sure why but I guess it has something to do with variable management on the stack and/or compiler design).
To answer your questions:
Calling C++ a "superset" of C is somewhat a misnomer. While they share basic syntax features, and you can even make all sorts of C library calls from C++, they have striking differences with respect to type safety, warnings vs. errors (C is more permissible), and compiler/preprocessor options.
Most contemporary C compilers understand legacy code (such as this appears to be). The C compiler holds the function parameter names sort of like "placeholders" until their type can be declared immediately following the function header name.
No real "purpose" other than again, this appears to be ancient code, and the style back in the day was like this. The "normal" approach is IMO the better, more intuitive way.
My suggestion:
unsigned int hash(register char *str, register unsigned int size)
{
// Definition
}
A word of advice: Consider abandoning the register keyword - this was used in old C programs as a way of specifying that the variable would be stored in a memory register (for speed/efficiency), but nowadays compilers are better at optimizing away this need. I believe that modern compilers ignore it. Also, you cannot use the & (address of) operator in C/C++ on a register variable.
I created a structure as:
typedef struct {
float real, img;
} cmplx;
and created a function as:
void input(cmplx *a){
scanf("%f + %f i", &a->real, &a->img); }
and called the function from main as:
cmplx a;
input(&a);
The execution stops when the scanf is reached. If floats are replaced by ints, the problem is solved. What is this behaviour? Is there a way I can use float for my problem?
The program was compiled on Turbo C, in MS-WINDOWS XP
It is hard to answer without knowing the error message that your program's execution stops with, but from your comment "is there any code i can write to tell compiler to link floating point library",
I suspect it may be this issue:
"Floating point formats not linked" is a Borland run-time error (Borland
C or C++, Turbo C or C++). Borland's compilers try to be smart and not
link in the floating- point (f-p) library unless you need it. Alas, they
all get the decision wrong. One common case is where you don't call any
f-p functions, but you have %f or other f-p formats in scanf() or
printf() calls. The cure is to call an f-p function, or at least force
one to be present in the link.
To do that, define this function somewhere in a source file but don't
call it:
static void forcefloat(float *p)
{
float f = *p;
forcefloat(&f);
}
It doesn't have to be in the module with the main program, as long as
it's in a module that will be included in the link.
If you have Borland C++ 3.0, the README file documents a slightly less
ugly work-around. Insert these statements in your program:
extern unsigned _floatconvert;
#pragma extref _floatconvert
Using this workaround, or a more modern compiler, will probably fix your issue.
Problem is with using years old C compiler like TurboC, as it works fine for me (I am Using DevC++)
check this discussion for similar issue
I am a Theoretical Physics research student, working in Cosmology. In course of my research I have use to rather huge library of Fortran codes and I used C for my programming needs.
I have been able to link the two programs in numerous test files and they work brilliantly. But for them I have been using the object files to link them all. But when I tried to run the real deal through C, include reference to the Fortran header files. They seem to integrate and call each other fine but the format of the Fortran header file is incomptible with the C compiler, so when it jumps to the header file it start throwing errors that it cannot understand the syntax.
For example, the Fortran header file defines double variables with real*8 so when C reads them it throws errors. The same happens with comments in the file as well.
So, I want to ask is there any way through which I can go about this problem? i.e. make the fortran format header file readible through C.
I looked over the internet and found confusing answers, and I do not know which one to follow. Any help in this matter will be appreciated :)
Sorry but you are very confusing. What is a Fortran header file ? For instance, you cannot read a Fortran include file using a C compiler ! The two languages are too different. In addition a Fortran include file is almost never an header file comparable to the C's one.
I don't know the kind of compiler you are using. But if you have chosen a recent GCC version (Gnu Compiler Collection), then the Fortran compiler included inside is able to take into account the ISO_C_BINDING feature which makes easier the coupling Fortran-C.
Example :
MODULE my_fortran
USE iso_c_binding
IMPLICIT NONE
CONTAINS
SUBROUTINE my_subroutine(a,b) BIND(C,name="my_sub")
INTEGER(c_int),INTENT(in),VALUE :: a
REAL(C_DOUBLE),INTENT(out) :: b
...
END SUBROUTINE
END MODULE
C header file named "my_sub.h" for instance :
void my_sub(int, double *);
C file
#include "my_sub.h"
int main(){
double b;
int a=3;
my_sub(a,&b);
...
}
Fortran usually passes its variables by reference (passes pointers).
That means that you MUST give addresses in your calling C-program.
Function results, may be passed by value, for example, the following
code calls a FORTRAN function called "gamma":
double x, y;
..................
x = 2.0;
y = gamma_(&x)
Make sure that the
size of the variable in the calling program is identical to the size
in the Fortran routine:
float --- REAL (this is typical, but not always the case)
double --- REAL*8
The Fortran function must be declared at the beginning of the C calling function:
extern void read_(int *small, float *medium, double *large);
Note we have to pass all variables to Fortran as pointers. Although the function name is not case sensitive in Fortran, it gains an underscore in the C declaration and when it is called:
read_(&small, &medium, &large);
The Fortran function receives the variables as follows:
SUBROUTINE READ(small,medium,large)
INTEGER small
REAL medium
DOUBLE large
The precise size of these variables depends on your system's architecture (32 bit verses 64 bit), so you need to confirm the correspondence between ints, floats and doubles in C and Fortran on your system.