I'm trying to learn how to use the GMP library in C by just writing a simple program to add some floating point numbers together, but at runtime it complains:
GNU MP: Cannot allocate memory (size=140735132293330)
Aborted (core dumped)
Here is the code:
#include <gmp.h>
#include <stdio.h>
int main(){
mpf_set_default_prec(64);
mpf_t sum;
mpf_init(sum);
mpf_set_ui(sum,0);
unsigned int i = 0;
while (i < 4) {
mpf_add_ui(sum,sum,i);
i++;
}
mpf_out_str(stdout,10,sum);
printf ("\n");
mpf_clear(sum);
}
I was able to do this with just the GMP mpz functions without issue, but when I try this with floats I'm stuck. The documentation doesn't really show any real examples for float functions so maybe I'm initializing or assigning the values incorrectly.
From the documentation,
it is a good idea to include stdio.h before gmp.h, since that will allow gmp.h to define prototypes for these functions
This way you get an error because you are calling the function with the wrong number of arguments. The reason you are not getting any warning for the lack of declaration is because mpf_out_str is a macro, defined in gmp.h which on your machine is installed in /usr/include and thus considered a system header, so the warning is disabled (use -Wsystem-headers to see it). This feels like a misfeature in gcc...
You must have not checked your compiler warnings properly, but the simple error is that you're calling mpf_out_str with the wrong number of arguments, which you can look up in the documentation:
size_t mpf_out_str (FILE *stream, int base, size_t n_digits, const mpf_t op)
// ^^^^^^^^^^^^^^^^
Related
I am programming a Teensy micro-controller as a part of a C course and am trying to work out the value of one of my integer variables. I have an integer variable called Contrast, which is initialised to the value of a constant defined as a hexadecimal number at the beginning of the .c file:
#define LCD_DEFAULT_CONTRAST 0x3F
int Contrast = LCD_DEFAULT_CONTRAST;
I am trying to investigate how this Contrast value is stored and displayed, if it shows up as 63 or 0x3F, and if they are interchangeable. I tried to use:
printf("%d", Contrast);
to print out the Contrast value to the terminal and I got the error implicit declaration of function 'printf'. I thought printf() was part of the built-in C library, so I am confused why this is not working.
Can anyone please tell me how I print the value of this variable to the screen?
The implicit declaration error just means your compiler proper doesn't have a declaration for printf. Unless you're also getting a linker error, the linker (linking usually follows compilation, unless you pass -c to disable it) is probably slapping the standard lib right on, in which case you can simply solve your warning by including stdio.h or less preferably by declaring int printf(char const*, ...);.
If you trully don't have the standard lib, you'll need to convert the integer to a string manually with something like:
int n = 42;
char buf[20];
char *end = buf+(sizeof(buf)-1), *p = end;
*p--=0;
if(n==0) *p=='0';
else{
while(n){
printf("%d\n", n%10);
*p--=n%10+'0';
n/=10;
}
p++;
}
and then pass it to your system's raw IO routine for which you'll need to have set up the system-entering assembly.
If you don't have a system, it'd be even more technical, and you probably wouldn't be asking this question.
printf() is declared in standard library header <stdio.h>.
You have to #include <stdio.h> to use printf(). It is a library call, much like all other library calls in C..
I strangely found that C allows linking of function where argument list doesn't match:
//add.c
int add(int a, int b, int c) {
return a + b + c;
}
//file.c
int add (int,int); //Note: only 2 arguments
void foo() {
add(1,2);
}
I compiled add.c first, then compiled file.c, both got compiled successfully. Strangely, linker didn't give any sort of error or warning, probably the reason is C linker doesn't compare arguments while linking. I'm not 100% sure about it though. Someone please comment on this.
Now, the question is what is the good practice to avoid this situation or get some sort of warning during compilation, because in my project there are lot of functions in different files, and now & then we have to add some extra argument in the function.
Use your header files correctly.
Configure your compiler to emit as many warnings as possible.
Mind the warnings!
add.h
#ifndef ADD_H_INCLUDED
#define ADD_H_INCLUDED
int add(int a, int b, int c);
#endif
add.c
#include "add.h"
int add(int a, int b, int c) {
return a + b + c;
}
file.c
#include "add.h"
void foo() {
add(1, 2);
}
C linker doesn't compare arguments while linking.
That is correct. Unlike C++ linker which considers argument types to be part of a function signature, C linker considers only function names. That is why it is possible to create a situation with undefined behavior simply by supplying a wrong function prototype the way that you show.
what is the good practice to avoid this situation or get some sort of warning during compilation?
Always put prototypes of functions that you are intended to share into a header, and include that header from the places where the function is used and the place where the function is defined. This would ensure that compiler issues a diagnostic message. Treat all compiler warnings as errors. C compilers are often rather forgiving, so their warnings usually indicate something very important.
Calling a function with to few arguments leads to undefined behavior as the value of those arguments will be indeterminate.
This question already has answers here:
Why does omitting explicit 'int' type for a parameter fail to compile in gcc sometimes?
(2 answers)
Closed 8 years ago.
I've read some, to me, peculiar C-code while studying some examples in the book The Unix Programming Environment (1983).
As a curiosity I wanted to find out more about the, let's call it "style". The point of interest here is the line just below int main(argc, argv)
#include <stdio.h>
int main(argc, argv)
char *argv[];
{
printf("%s\n", argv[0]);
return 0;
}
In my investigation I've found that compiling the above code with the flags -Wall -pedantic -ansi works without any warnings, and replacing -ansi with the more recent -std=c99 (or c11, with gcc and cc) only warns about argc defaulting to int.
I perused the old C89 standard trying to find references to this particular way of writing
but didn't find anything on my own so I defer to the greater knowledge of the collective.
Hence the question, from when does this esoteric writing stem and possibly why is it still allowed (legacy reasons?)
The old way to do things was to have functions without prototypes. Functions return int by default, and since the function parameter types are unknown at the call site, you better get it right. This frees you from having to maintain header files, but for various reasons, it is no longer recommended.
// In func.c
// Default to int return
func(x, y)
int x;
int y;
{
return x + y;
}
// In main.c
main(argc, argv)
int argc;
char **argv;
{
int result = func(2, 3);
}
This causes problems if you get the function parameter types wrong.
int result = func(2.0, 3,0); // Wrong, but no compiler error or warning
It was normal to call functions without including the relevant header file. But you need to declare the function return type.
// This is NOT a function prototype, it just declares the return type.
double sin();
double one = sin(3.14); // Correct
double zero = sin(0); // WRONG
double zero = sin(0.0); // Correct
Old style functions are still allowed by the standard, except the default return type is gone. This allows you to compile old programs. For new programs, the -Wmissing-prototypes option in GCC helps you to avoid using the old style by accident.
int func(); // Old-style, can take any number of arguments.
int func(void); // New-style, takes no arguments, is a function prototype.
This is good old fashioned K&R C.
Everything is by default an integer, and you define the actual types of parameters in functions, not in the prototype, but in a separate declaration list. It made writing integer-only code easier, but made debugging function calls a nightmare.
Here's a function written in both styles.
int myFunc(const char *from, char *to, int len); // Ah that feels right, doesn't it
int myFunc(const char *from, char *to, int len){} // And here's the definition
myKRFunc(); /* Okay, that's a declaration */
myKRFunc(from, to, len) /* Yep, you just write the parameter names here */
char *from, *to; /* And you can write normal declarations, len defaults to an int */
{}
I wanted to explain why debugging function calls without prototypes was harder, but Dietrich covers it in his answer well.
This is the original K&R style C. It's still legal, because why not? Backwards compatibility lets people move forward in small steps. That's the pain of any popular evolving system.
This is based on the old "standard", so I wouldn't worry too much about it. I definitely don't recommend programming in that style, but it's useful to know it exists in case you encounter more legacy code.
What could be the issue here? It doesn't matter what number I choose for str, it is always 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
char *str = "2.6";
printf("%f\n", strtof(str, (char**)NULL));
//prints 26815615859885194199148049996411692254958731641184786755447122887443528060147093953603748596333806855380063716372972101707507765623893139892867298012168192.00
whole program:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *str = "2.6";
printf("%f\n", strtof(str, NULL));
return 1;
}
compile with -Wall:
test4.c:7: warning: implicit declaration of function âstrtofâ
What platform are you building for/on? The warning that you say is being emitted:
test4.c:7: warning: implicit declaration of function âstrtofâ
indicates that the compiler doesn't know that strtof() returns a float, so it's going to push an int to the printf() call instead of a double. strtof() is normally declared in stdlib.h, which you're including. But it wasn't a standard function until C99, so the exact compiler platform (and configuration/options you're using) may affect whether it's being made available or not.
strtof is defined in C99 only. It may be that passing the option -std=c99 to the compiler will fix it since default GCC (-std=gnu89) includes only a few C99 features.
Another option is to use the C89-kosher strtod. Which is probably the better option in the long run, anyways. (When do you need singles except in exceptional circumstances?)
Perhaps you've forgotten to include the correct header(s)?
#include <stdlib.h>
#include <stdio.h>
int main() {
printf("%f\n", strtof("2.6", NULL));
return 0;
}
produces:
2.600000
for me...
Given your warnings, you should try adding -std=c99 to get the C99 standard definitions from the header. By default it will assume that the return value is an int and then try to convert that to a float. This will obviously be wrong. Alternatively you could simply supply your own, correct declaration for strtof().
As the others have said, you need -std=c99. But you can also use strtod() which is string to double, and you don't need -std=c99 for that.
I was having problems with strtof() on CentOS 5.5 with glibc 2.5 unless I used -std=c99, but strtod() worked perfectly.
I have an Objective C project incorporating a C file with some helper functions. However, functions in the C file that return a float are not working as expected.
C file:
float returnFloat() {
return 10.0;
}
Meanwhile in an Objective C instance method:
float x;
x = returnFloat();
x is always 0.000000.
Edit
I have a bunch of "implicit declaration" warnings in the Objective C file, relating to use of the functions I have in the C file.
Assignments using functions that return int are working fine. Where an assignment is made from a function returning float, the debugger says "variable optimized away by compiler".
Is it likely I'm not correctly importing the C file within the Objective-C code? I have just let Xcode link it in automagically. Then, how come the problem only occurs for C functions that return float?
You have to use a .h file, just like with .m files, to declare what you're doing in another file. So, you need something like this for this scenario (these are incomplete):
returnfloat.c
float returnFloat() {
return 10.0;
}
returnfloat.h
float returnFloat(void);
usefloat.m
#import "returnfloat.h"
- (void) someMethod {
float ten = returnFloat();
}
The problem (given away by your "implicit declaration" warnings) is that the compiler is assuming that you are calling something that returns an int or id, not a float. When you work with C, things need to be prototyped (GCC will treat the .c file like C, and all C rules apply, even though you're in an Objective-C project).
If you'd like to see an example, here's something from one of my projects -- production code (you can write pure C in a file ending in .m, and GCC will treat it like Objective-C in some ways):
DebugF.m
#import "DebugF.h"
void __Debug(const char *file, int line, NSString *format, ...) {
#ifdef DEBUG
/* Wraps NSLog() with printf() style semantics */
#endif
}
DebugF.h
#ifndef __DEBUGF_H_INCLUDED__
#define __DEBUGF_H_INCLUDED__
#ifdef DEBUG
#define DebugF(args...) __Debug(__FILE__, __LINE__, args)
#else
#define DebugF(...)
#endif /* DEBUG */
void __Debug(const char *file, int line, NSString *fmt, ...);
#endif /* __DEBUGF_H_INCLUDED */
SomeViewController.m
DebugF(#"Got these arguments: %u, %#, %#", 4, anObject, [anObject somethingElse]);
I'm no Objective-C programmer, but in C world the compiler assumes int return type for any undeclared function that current module uses. It looks to me that creating a normal C header file containing:
#ifndef _MY_IMPORTANT_HEADER_
#define _MY_IMPORTANT_HEADER_
extern float returnFloat();
#endif
and including that into your .m file should make it all work:
#include "myheader.h"
How did you declare 'returnFloat()' to your Objective-C program? Does it have a prototype in scope? If not, then your likely problem is that Objective-C is treating the function as returning an int, not a float, and havoc ensues (or you perceive that zero is returned).
It's cause you want:
// the c way
float returnFloat() {
return 10.0;
}
float result = returnFloat();
// the objective-c way
- (float) returnFloat {
return 10.0;
}
float result = [self returnFloat]; // assuming this is an object
Not what you have. You're mixing C function prototypes with Objective-C. Try the C way mentioned above (Should be able to use it in Objective-C code).
Sorry if I misunderstood your question, I'm pretty sure my code is correct :)
EDIT: Clarification for all of the downvoters. In his first revision of the post he made it float returnFloat {} instead of float returnFloat() { }, which prompted my answer.
EDIT 2: Apparently that wasn't clear enough. In his first revision of his post, he was mixing the C way of writing function prototypes with the Objective-C way of writing function prototypes. You CAN use C functions in Objective-C, but you CAN'T mix the way of writing their function prototypes, as I explained above. Sorry for any confusion.
How are you determining that x is 0.0000? A common mistake in debugging is to use the wrong format string in NSLog().
If you are, using NSLog(), make sure you're using the %f or some variant of it:
NSLog(#"x = %f", x);
(many people get mixed up and try to use %i instead)
EDIT: That's with the assumption that your C function prototype is correct and the lack of parentheses was just a typo here. If not, Blaenk's answer is likely correct.