Compiling mathgl C-Example - c

I'm trying to compile the first example of the MathGL library in C:
http://mathgl.sourceforge.net/doc_en/Examples.html
#include <mgl2/mgl_cf.h>
int main()
{
HMGL gr = mgl_create_graph(600,400);
mgl_fplot(gr,"sin(pi*x)","","");
mgl_write_frame(gr,"test.png","");
mgl_delete_graph(gr);
}
I installed libmgl-dev using aptitude and rejected the first option offered, because aptitude wanted to remove a number of different programs and accepted the second option, which only upgraded a few.
If I try to compile:
gcc test.c -o test -lmgl
In file included from /usr/include/mgl2/mgl_cf.h:29:0,
from test.c:1:
/usr/include/mgl2/data_cf.h:318:78: error: unknown type name ‘bool’
EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, bool inv);
So I tried to add #include <stdbool.h> and tried flags like -std=gnu11 or -std=c11 and -std=c99. None of which worked. I tried adding the flag -lmgl (I even read that I should put it at the very end).
How do I compile this example?

You appear to have an old version of the library, in which this is a bug.
See this bug report
from May 2013. The Alexey Balakin who confirms the bug is the lead developer of MathGL.
See that the bug is fixed in MathGL 2.3.3 version of data_ch.h,
where the declaration is:
void MGL_EXPORT mgl_fft(double *x, long s, long n, const void *wt, void *ws, int inv);
with bool replaced by int.

Related

GCC ignoring the "access" function-attribute?

I am currently getting into using attributes using c. However when trying to use the "access" attribute for funtions. However when compiling I get a warning saying the attribute is ignored.
This is a minimal example that has this issue arise:
#include <stdio.h>
__attribute__ ((access (read_only,1))) void printAll(double * arr,size_t size){
for(int i=0;i<size;i++) printf("%lf\n", arr[i]);
}
int main(){
double testArr[]={1,2,3,4,5,6};
printAll(testArr,6);
}
The compiler gives the following warning:
warning: 'access' attribute directive ignored [-Wattributes] __attribute__ ((access (read_only,1))) void printAll(double * arr,size_t size){
I read about this issue arising with other attributes.
And one solution was that the gcc version may be relevant.
I still have gcc version 8.3.0 from an older installation.

No output from split up source, but no warnings either, when omitting an included file

I ran into an issue invoking gcc where if I omit a library .c file, I got no output from the binary (unexpected behavior change) but since this is a missing dependency, I kind of expected the compile to fail (or at least warn)...
Example for this issue is from Head First C page 185 (but is not errata, see my compile mis-step below):
encrypt.h:
void encrypt(char *message);
encrypt.c:
#include "encrypt.h"
void encrypt(char *message)
{
// char c; errata
while (*message) {
*message = *message ^ 31;
message++;
}
}
message_hider.c:
#include <stdio.h>
#include "encrypt.h"
int main() {
char msg[80];
while (fgets(msg, 80, stdin)) {
encrypt(msg);
printf("%s", msg);
}
}
NOW, everything works fine IF I faithfully compile as per exercise instruction:
gcc message_hider.c encrypt.c -o message_hider
... but bad fortune led me to compile only the main .c file, like so:
$ gcc message_hider.c -o message_hider
This surprisingly successfully builds, even if I added -Wall -Wextra -Wshadow -g.
Also surprisingly, it silently fails, with no output from encrypt() function:
$ ./message_hider < ./encrypt.h
$
my gcc is:
$ /usr/bin/gcc --version
Apple clang version 13.1.6 (clang-1316.0.21.2.5)
Target: x86_64-apple-darwin21.6.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
Mindful that even with a Makefile, I could "still" end up with a missing .c file due to a mistake in the recipe.
Q: Is it possible to force a hard error if I forget to tell gcc about a .c file?
As I noted in a (misspelled) comment:
There is probably a function encrypt() in the system library.
On a Mac, man -s 3 encrypt shows:
CRYPT(3) BSD Library Functions Manual CRYPT(3)
NAME
crypt, encrypt, setkey -- DES encryption
SYNOPSIS
#include <unistd.h>
char *
crypt(const char *key, const char *salt);
void
encrypt(char *block, int edflag);
#include <stdlib.h>
void
setkey(const char *key);
…
The encrypt() and setkey() functions are part of POSIX, so they'll be available on most POSIX-like systems. Curiously, as shown in the manual page extract, the functions are declared in separate headers — <unistd.h> for encrypt() and
<stdlib.h> for setkey(). There's probably a good (enough) historical reason for the disconnect.
You should have received a compiler warning about the function being undeclared — if you didn't, you are presumably compiling using the C90 standard. That is very old and should not still be being taught; you need to be learning C11 or C18 (almost the same).
Since C99, the C standard requires functions to be declared before use — you can define a static function without pre-declaring it, but all other functions (except main()) should be declared before they are used or defined. You can use GCC compiler warning options such as -Wmissing-prototypes -Wstrict-prototypes (along with -Wold-style-declaration and -Wold-style-definition) to trigger warnings. Of these, -Wold-style-declaration is enabled by -Wextra (and none by -Wall). Be aware: as noted in the comments, clang does not support -Wold-style-declaration though true GCC (not Apple's clang masquerading as gcc) does support it.

No parameter checking in GCC

I have written a C program, which consists below given three files in same directory
main.c
#include<stdio.h>
#include "test.h"
int main()
{
int b=0;
b = test_add(3,2);
printf("Added: b=%d\n\n",b);
return 0;
}
test.h
int test_add(int a, int b);
test.c
int test_add(int a, int b, int c)
{
return a+b+c;
}
I am compiling the program using below command:
$gcc -Wall -Wextra main.c test.c
It compiles successfully. I can see there is mismatch in number of arguments of calling function and its actual definition. Compiler doesn't give any warning/error for such problem. How can this type of errors be reported by compiler?
This shows one of the oddities of the C standard. It allows entities such as functions to be undefined.
The actual error is that you did not
#include "test.h"
in you test.c file.
That means that the main file only sees the version of the function with three parameters. When it reaches the function call, it implicitly declares the function with two parameters.
When you run it, you get bogus values for b. I am guessing the superuser's password could somehow be in there ;)
If you add the include directive, you get an error at compile time.
What worries me, that there is no warning, not even with -Wall -Wextra -pedantic.

Cygwin cannot find dos.h and conio.h on compilation

I am trying to compile the following code in Cygwin 64 bit terminal using gcc, but it seems to be unable to find conio.h or dos.h
#include <stdlib.h>
#include <dos.h>
#define MEM 0X12
main()
{
struct WORDREGS
{
unsigned int ax;
unsigned int bx;
unsigned int cx;
unsigned int dx;
unsigned int si;
unsigned int di;
unsigned int flags;
};
struct BYTEREGS
{
unsigned char al,ah;
unsigned char bl,bh;
unsigned char cl,ch;
unsigned char dl,dh;
};
union REGS
{
struct WORDREGS x;
struct BYTEREGS h;
};
union REGS regs;
unsigned int size;
int86(MEM, &regs, &regs);
size = regs.x.ax;
printf("Memory size is %d Kbytes", size);
}
The compiler says it is unable to locate dos.h or conio.h, showing a fatal error notice. I want to know what the reason for this is and how it can be dealt with.
Cygwin is a Linux-Environment for Windows (see https://cygwin.com ). This is probably the main reason because there very well exists a header file called 'dos.h'.
Concerning the compilation problem a solution is explained in the mail archive of the cygwin mailing list ( https://www.cygwin.com/ml/cygwin/2007-04/msg00180.html ).
It seems that dos.h and conio.h (header-files) are part of the mingw-runtime-WHATEVER.VERSION package, which you can download from cygwin.com (better install it with the cygwin install and update program setup-x86.exe or setup-x86_64.exe).
The link in that mail mentioned above is broken, but you can find the package by yourself, when choosing 'Search Packages' on the left side bar of the cygwin.com homepage. Then you can put 'dos.h' or 'conio.h' into the input field and after hitting 'Go' you get listed all packages, which contain these header files. According to the answer in that mail above, you only need the
mingw-runtime-WHATEVER.VERSION package, which you have to download and install.
After installing that package you very probably need to instruct your gcc-compiler with the
option '-I' (upper-case letter 'i'!) and the path (within quotation marks!) to the dos.h file, for instance:
gcc program.c -I'C:\cygwin\usr\i686-pc-mingw32\sys-root\mingw\include'
Attention: Probably the path on your system is different, particularly when you are working with 64-bit-cygwin!
Instead of using the '-I' option, you can define an environment variable with following command in the terminal:
export C_INCLUDE_PATH='C:\cygwin\usr\i686-pc-mingw32\sys-root\mingw\include'
At least the errors with the not found header-files are then eliminated, but there are probably still other errors (for instance: undefined reference to 'int86'?).
Because they are MS-DOS headers and are not available in cygwin. Also, the correct signature of main() is int main().

"undefined reference to 'cblas_ddot'" when using cblas library

I was testing the cblas ddot, and the code I used is from the link and I fixed it as
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main()
{
double m[10],n[10];
int i;
int result;
printf("Enter the elements into first vector.\n");
for(i=0;i<10;i++)
scanf("%lf",&m[i]);
printf("Enter the elements into second vector.\n");
for(i=0;i<10;i++)
scanf("%lf",&n[i]);
result = cblas_ddot(10, m, 1, n, 1);
printf("The result is %d\n",result);
return 0;
}
Then when I compiled it, it turned out to be:
/tmp/ccJIpqKH.o: In function `main':
test.c:(.text+0xbc): undefined reference to `cblas_ddot'
collect2: ld returned 1 exit status
I checked the cblas file in /usr/include/cblas.h, and noticed there is
double cblas_ddot(const int N, const double *X, const int incX,
const double *Y, const int incY);
I don't know where it is going wrong. Why does the compiler said the "cblas_ddot" is undefined reference?
You can't just include the header - that only tells the compiler that the functions exist somewhere. You need to tell the linker to link against the cblas library.
Assuming you have a libcblas.a file, you can tell GCC about it with -lcblas.
The web site for GNU Scientific Library tells you how to do this:
2.2 Compiling and Linking
My problem was just solved. The reason is that I made a mistake when inputed the link path. Thanks for Jonathon Reinhart's answers, they are really helpful when learning how to code in linux.
The compile commands are:
gcc -c test.c
gcc -L/usr/lib64 test.o -lgsl -lgslcblas -lm
Where "/usr/lib64" is the correct link path.

Resources