Tux

...making Linux just a little more fun!

Debian Issues

Amit Kumar Saha [amitsaha.in at gmail.com]


Fri, 17 Aug 2007 14:45:25 +0530

hello,

I have been facing a couple of "weird" issues on Debian 4.0

1. Every time (on a new boot) I have to "listen" to a video song, I have to run "alsaconf". I can see the video and listen to audio files but not the video songs until i run "alsaconf"

2. GCC reports linker error while using "sin", "cos", etc. However it is solved when i append a "-lm" during compilation

Waiting for some insights!

Thanks

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


Steve Brown [steve.stevebrown at gmail.com]


Fri, 17 Aug 2007 12:18:11 +0100

Hi Amit,

On 17/08/07, Amit Kumar Saha <amitsaha.in@gmail.com> wrote:

>
> 2. GCC reports linker error while using "sin", "cos", etc. However it
> is solved when i append a "-lm" during compilation
>

You are including the maths libraries when you compile your program with "-lm" (think Link Maths)

You can include this line in your source file file to do the same (omit the -lm flag in this case)

#include <math.h>

More can be found here: http://aplawrence.com/Linux/c_compiling_linux.html

Hope this helps,

Steve


Top    Back


Jim Jackson [jj at franjam.org.uk]


Fri, 17 Aug 2007 14:30:11 +0100 (BST)

On Fri, 17 Aug 2007, Steve Brown wrote:

> Hi Amit,
>
> On 17/08/07, Amit Kumar Saha <amitsaha.in@gmail.com> wrote:
> >
> > 2. GCC reports linker error while using "sin", "cos", etc. However it
> > is solved when i append a "-lm" during compilation
> >
>
> You are including the maths libraries when you compile your program
> with "-lm" (think Link Maths)
>
> You can include this line in your source file file to do the same
> (omit the -lm flag in this case)
>
> #include <math.h>

Er... you can and maybe should put that include in your source, but it is NOT a substitute for linking with the correct library.

as this page ...

> More can be found here: http://aplawrence.com/Linux/c_compiling_linux.html

actually mentions...

... And there may even be more to do. Look at this:

#include <stdio.h>
#include <math.h>
main ()
{
printf("pi = %.5f\n", 4 * atan(1.0));
}
We looked up the atan function and found it needs math.h. We've told the compliler to include it. Trust me, the program is right. But..

$ gcc -o pi pi.c
/tmp/ccLmoMxc.o(.text+0x33): In function `main':
: undefined reference to `atan'
collect2: ld returned 1 exit status
What we need here is a special compiler flag:

gcc -o pi -lm pi.c
"lm" tells it to link in the math libraries. Math libraries? Sure, you didn't think C by itself knows how to do arc tangents, did you? C by by itself doesn't know much. Most of its functions - the things you can use - come from external libraries that get linked in. How would you know when you need to use a special library? It's just something you have to learn. Usually, if there is a special linker flag, the man page will have told you. In the case of atan, it does not, so you just need to remember that you need "-lm" when you see "#include <math.h>" mentioned."

cheers Jim


Top    Back


Steve Brown [steve.stevebrown at gmail.com]


Fri, 17 Aug 2007 14:44:10 +0100

Hi Jim,

thanks for the clarification, I should really have read more of the link I mentioned.

It's been years since I did anything in C and I thought I knew the answer.

On reflection, I included the information needed to access the libraries - the header file, but not told the linker to include them at compilation. Doh!

[Scuttles off to read 'C for Real Dummies']

Steve


Top    Back


René Pfeiffer [lynx at luchs.at]


Fri, 17 Aug 2007 16:21:24 +0200

On Aug 17, 2007 at 1444 +0100, Steve Brown appeared and said:

> [...]
> On reflection, I included the information needed to access the
> libraries - the header file, but not told the linker to include them
> at compilation. Doh!

Well, yes, C basically means "yeah, I can take care of all the details". First thing I do when writing C is to create the Makefile. Here's an example from a little tool named "dailywtlpg" I am working on:

CC =3D colorgcc
CFLAGS =3D -I. -I/usr/local/pgsql/include -DDEBUG -g
LDFLAGS=3D -L/usr/local/pgsql/lib -lpq -lpcre
 
# For Intel ICC and Core 2 Duo use:
# /opt/intel/cc/9.1.042/bin/icc -I. -xP -DDEBUG -o dailywtl dailywtl.c
 
DEPS =3D dailywtlpg.h
OBJDAILYWTL =3D dailywtlpg.o
 
%.s: %.c $(DEPS)
	$(CC) -S -o $@ $< $(CFLAGS)
 
%.o: %.c $(DEPS)
	$(CC) -c -o $@ $< $(CFLAGS)
 
dailywtlpg: $(OBJDAILYWTL)
	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
all: dailywtlpg
The first lines define CC, the compiler, and the flags being used for the compiler and linker runs. Put all desirable include paths into CFLAGS and put the paths for the corresponding libraries into LDFLAGS. Both will be used when calling the compiler.

DEPS lists all dependencies, OBJDAILYWTL lists all object files. "%.s" defines a rule to create .s files (assembler listings, I am curious ;), "%.o" defines a rule for creating object files. The last two rules explain how make should create the dailywtlpg binary and what needs to be done when "make all" is executed.

Best, René.


Top    Back


Steve Brown [steve.stevebrown at gmail.com]


Fri, 17 Aug 2007 16:07:31 +0100

Hi René,

On 17/08/07, René Pfeiffer <lynx@luchs.at> wrote:

[[[ content snipped - Kat ]]]

> The first lines define CC, the compiler, and the flags being used for
> the compiler and linker runs. Put all desirable include paths into
> CFLAGS and put the paths for the corresponding libraries into LDFLAGS.
> Both will be used when calling the compiler.
>
> DEPS lists all dependencies, OBJDAILYWTL lists all object files. "%.s"
> defines a rule to create .s files (assembler listings, I am curious ;),
> "%.o" defines a rule for creating object files. The last two rules
> explain how make should create the dailywtlpg binary and what needs to
> be done when "make all" is executed.
>

Do you know, sometimes getting an answer just allows you to think of more questions. I'm off to look into C programming again all because of one little email and make as well.

Steve


Top    Back


Jim Jackson [jj at franjam.org.uk]


Fri, 17 Aug 2007 15:41:55 +0100 (BST)

On Fri, 17 Aug 2007, Steve Brown wrote:

> Hi Jim,
>
> thanks for the clarification, I should really have read more of the
> link I mentioned.
>
> It's been years since I did anything in C and I thought I knew the answer.
>
> On reflection, I included the information needed to access the
> libraries - the header file, but not told the linker to include them
> at compilation. Doh!

It's a very common misconception. Actually including the header files doesn't really "access" the libraries. It generally simply includes the library function prototypes, and any macros/defines that the library writer documents or requires as useful for calling the library functions. These files are simple C code text files in /usr/include (usually) - take a look at say /usr/include/math.h - there is no C code - just a bunch of (admittedly complicated) #defines and typedefs.

The functions are in the library object files and the c compiler has to be told which library to link into the program with the '-lxxx' compiler flag. The precompiled library will be found in one of a series of "prefined" library directories, usually /lib /usr/lib , as the file "libxxx.so" or for non-shared libraries "libxxx.a".


Top    Back


Steve Brown [steve.stevebrown at gmail.com]


Fri, 17 Aug 2007 15:54:18 +0100

Hi Jim,

On 17/08/07, Jim Jackson <jj@franjam.org.uk> wrote:

> On Fri, 17 Aug 2007, Steve Brown wrote:
> > On reflection, I included the information needed to access the
> > libraries - the header file, but not told the linker to include them
> > at compilation. Doh!
>
> It's a very common misconception. Actually including the header files
> doesn't really "access" the libraries. It generally simply includes the
> library function prototypes, and any macros/defines that the library
> writer documents or requires as useful for calling the library functions.
> These files are simple C code text files in /usr/include (usually) - take
> a look at say /usr/include/math.h - there is no C code - just a bunch of
> (admittedly complicated) #defines and typedefs.
>
> The functions are in the library object files and the c compiler has to be
> told which library to link into the program with the '-lxxx' compiler
> flag. The precompiled library will be found in one of a series of
> "prefined" library directories, usually /lib /usr/lib , as the file
> "libxxx.so" or for non-shared libraries "libxxx.a".
>

I last programmed in C on my old Amiga - just little bits and pieces so it's been a while. Sadly it's all coming back to me now after I chewed my foot for a bit ;)

I may just have to go off and take a look at those headers now my curiosity has been nudged. I used to read the Amiga reference manuals almost daily, it's a bit sad that I've forgotten so much.

Steve


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Fri, 17 Aug 2007 20:08:30 +0530

Hi Jim,

> Er... you can and maybe should put that include in your source, but it
> is NOT a substitute for linking with the correct library.
>
> as this page ...
>
> > More can be found here: http://aplawrence.com/Linux/c_compiling_linux.html
>
> actually mentions...
>
> "
> ... And there may even be more to do. Look at this:
>
> #include <stdio.h>
> #include <math.h>
> main ()
> {
> printf("pi = %.5f\n", 4 * atan(1.0));
> }
>
> We looked up the atan function and found it needs math.h. We've told the
> compliler to include it. Trust me, the program is right. But..
>
> $ gcc -o pi pi.c
> /tmp/ccLmoMxc.o(.text+0x33): In function `main':
> : undefined reference to `atan'
> collect2: ld returned 1 exit status
>
> What we need here is a special compiler flag:
>
> gcc -o pi -lm pi.c
>
> "lm" tells it to link in the math libraries. Math libraries? Sure, you
> didn't think C by itself knows how to do arc tangents, did you? C by by
> itself doesn't know much. Most of its functions - the things you can use -
> come from external libraries that get linked in. How would you know when
> you need to use a special library? It's just something you have to learn.
> Usually, if there is a special linker flag, the man page will have told
> you. In the case of atan, it does not, so you just need to remember that
> you need "-lm" when you see "#include <math.h>" mentioned."

Funny it is, I have been programming C using GCC for past 4 years or so, this is for the first time I am using a trigonometric function and I learn that I have to link the math library "-lm" to be able to actually use them. {Moron me :( }

By the way, is "pow ()" also defined in "math.h" ? If yes, then it compiles correctly for me without adding the "-lm".

Consider the following program :

#include <stdio.h>
#include <math.h>
 
int main(){
printf("%d\n",pow(3,2));
return 0;
}
 
OUTPUT:
 
amit@etch-desktop:~/junk$ gcc MathDemo.c
amit@etch-desktop:~/junk$ ./a.out
0
Could some one please explain the above output?

Regards

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


René Pfeiffer [lynx at luchs.at]


Fri, 17 Aug 2007 17:17:14 +0200

On Aug 17, 2007 at 2008 +0530, Amit Kumar Saha appeared and said:

> [...]
> Consider the following program :
> #include <stdio.h>
> #include <math.h>
> int main(){
> printf("%d\n",pow(3,2));
> return 0;
> }
> OUTPUT:
> amit@etch-desktop:~/junk$ gcc MathDemo.c
> amit@etch-desktop:~/junk$ ./a.out
> 0
> Could some one please explain the above output?

Using "-Wall" is a good habit when calling the compiler (as much as using "strict" when coding Perl):

lynx@agamemnon:/tmp $ gcc -Wall math.c=20
math.c: In function =E2=80=98main=E2=80=99:
math.c:5: warning: format =E2=80=98%d=E2=80=99 expects type =E2=80=98int=E2=
=80=99, but argument 2 has
type =E2=80=98double=E2=80=99
lynx@agamemnon:/tmp=20
pow() returns floating point data, but your format string expects an integer type, so I suspect that the conversion inside printf() fails because it isn't considering all the bits. If you change the format string to "%f\n" everything's fine.

Best, René.


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Fri, 17 Aug 2007 22:01:02 +0530

On 8/17/07, René Pfeiffer <lynx@luchs.at> wrote:

> lynx@agamemnon:/tmp $ gcc -Wall math.c
> math.c: In function 'main':
> math.c:5: warning: format '%d' expects type 'int', but argument 2 has
> type 'double'
> lynx@agamemnon:/tmp
>
> pow() returns floating point data, but your format string expects an
> integer type, so I suspect that the conversion inside printf() fails
> because it isn't considering all the bits. If you change the format
> string to "%f\n" everything's fine.

My C knowledge so far would make me believe, that in a situation where "%d" is used instead of "%f" the numbers after the "." would be truncated, and only the integral portion displayed.

However as it has turned out, I can never call myself equipped with adequate C knowledge. As a matter of fact, I always felt C is too mysterious to be mastered fully by any one, we can only try to master some part of it :)

Regards

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


René Pfeiffer [lynx at luchs.at]


Fri, 17 Aug 2007 20:45:12 +0200

On Aug 17, 2007 at 2201 +0530, Amit Kumar Saha appeared and said:

> [...]
> My C knowledge so far would make me believe, that in a situation where
> "%d" is used instead of "%f" the numbers after the "." would be
> truncated, and only the integral portion displayed.

If you're doing C, then most functions take your instructions literally. Make sure that you always use matching types when putting variables into function calls. The GCC option "-Wall" is a good thing to use in order to catch some errors. Also if you have Intel's C Compiler "lying around" you can "crosscompile" your code with it. ICC is a lot more picky about C constructs than GCC.

> However as it has turned out, I can never call myself equipped with
> adequate C knowledge. As a matter of fact, I always felt C is too
> mysterious to be mastered fully by any one, we can only try to master
> some part of it :)

Knowing the assembly language of the CPU where the C program runs helps, too. ;)

Best, René.


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Sat, 18 Aug 2007 00:25:16 +0530

On 8/18/07, René Pfeiffer <lynx@luchs.at> wrote:

> Knowing the assembly language of the CPU where the C program runs helps,
> too. ;)

Someday, when I have lots of time to play around and the only thing in the world to do is C programming, I swear I shall decipher each instruction upto assembly language level that are executed even when I say "Hello World" using C statements!

Regards

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


Kapil Hari Paranjape [kapil at imsc.res.in]


Sat, 18 Aug 2007 08:54:46 +0530

Hello,

On Sat, 18 Aug 2007, Amit Kumar Saha wrote:

> Someday, when I have lots of time to play around and the only thing in
> the world to do is C programming, I swear I shall decipher each
> instruction upto assembly language level that are executed even when I
> say "Hello World" using C statements!
	gcc -S hello.c
	cat hello.s
Regards,

Kapil. --


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Sat, 18 Aug 2007 18:38:13 +0530

Hi ,

On 8/18/07, Kapil Hari Paranjape <kapil@imsc.res.in> wrote:

> Hello,
>
> On Sat, 18 Aug 2007, Amit Kumar Saha wrote:
> > Someday, when I have lots of time to play around and the only thing in
> > the world to do is C programming, I swear I shall decipher each
> > instruction upto assembly language level that are executed even when I
> > say "Hello World" using C statements!
>
>         gcc -S hello.c
>         cat hello.s
>

I have written these lines some time ago when I was playing with Assembly on Linux. I still want to play with them, but I am far from actually doing that. Blame it on a busy schedule which does not leave time for having fun :(

Thanks,

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


Jim Jackson [jj at franjam.org.uk]


Fri, 17 Aug 2007 20:31:47 +0100 (BST)

On Fri, 17 Aug 2007, Amit Kumar Saha wrote:

> Funny it is, I have been programming C using GCC for past 4 years or
> so, this is for the first time I am using a trigonometric function and
> I learn that I have to link the math library "-lm" to be able to
> actually use them. {Moron me :( }

I checked the man page on my (slightly old) debian box, and while it mentions including math.h, it makes no mention of linking with libm which I would expect it to do.

> By the way, is "pow ()" also defined in "math.h" ? If yes, then it
> compiles correctly  for me without adding the "-lm".

Well it doesn't for me.

pwr.c:(.text+0x50): undefined reference to `pow'
> Consider the following program :
>
> #include <stdio.h>
> #include <math.h>
>
> int main(){
> printf("%d\n",pow(3,2));
> return 0;
> }
>

why are you telling printf to print an integer (%d) when you are giving it double? Use one of the double conversion specs. %e or %f or %g, see man 3 printf for the gory details.

> OUTPUT:
>
> amit@etch-desktop:~/junk$ gcc MathDemo.c
> amit@etch-desktop:~/junk$ ./a.out
> 0
>
> Could some one please explain the above output?
>
> Regards
> --
> Amit Kumar Saha
> [URL]:http://amitsaha.in.googlepages.com
>
> +-+--------------------------------------------------------------------+-+
> You've asked a question of The Answer Gang, so you've been sent the reply
> directly as a courtesy.  The TAG list has also been copied.  Please send
> all replies to tag@lists.linuxgazette.net, so that we can help our other
> readers by publishing the exchange in our monthly Web magazine:
>               Linux Gazette (http://linuxgazette.net/)
> +-+--------------------------------------------------------------------+-+
> _____________________________________________
> TAG mailing list
> TAG@lists.linuxgazette.net
> http://lists.linuxgazette.net/mailman/listinfo/tag
>


Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Sat, 18 Aug 2007 01:20:09 +0530

On 8/18/07, Jim Jackson <jj@franjam.org.uk> wrote:

>
>
> I checked the man page on my (slightly old) debian box, and while it
> mentions including math.h, it makes no mention of linking with libm
> which I would expect it to do.

The man page on Debian etch mentions it.

Thanks!

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


Amit Kumar Saha [amitsaha.in at gmail.com]


Fri, 17 Aug 2007 19:58:21 +0530

Hi Steve,

>
> You are including the maths libraries when you compile your program
> with "-lm" (think Link Maths)
>
> You can include this line in your source file file to do the same
> (omit the -lm flag in this case)
>
> #include <math.h>

Actually I had already included the header file before I reported the error.

Thanks,

-- 
Amit Kumar Saha
[URL]:http://amitsaha.in.googlepages.com

Top    Back


Steve Brown [steve.stevebrown at gmail.com]


Fri, 17 Aug 2007 15:55:28 +0100

Hi Amit,

On 17/08/07, Amit Kumar Saha <amitsaha.in@gmail.com> wrote:

> Actually I had already included the header file before I reported the error.

Yes, I went off a bit too soon and made a mistake, sorry.

Steve


Top    Back


Neil Youngman [ny at youngman.org.uk]


Sun, 19 Aug 2007 18:39:55 +0100

On or around Friday 17 August 2007 12:18, Steve Brown reorganised a bunch of electrons to form the message:

> Hi Amit,
>
> On 17/08/07, Amit Kumar Saha <amitsaha.in@gmail.com> wrote:
> > 2. GCC reports linker error while using "sin", "cos", etc. However it
> > is solved when i append a "-lm" during compilation
>
> You are including the maths libraries when you compile your program
> with "-lm" (think Link Maths)
>
> You can include this line in your source file file to do the same
> (omit the -lm flag in this case)
>
> #include <math.h>

You're confusing 2 different things here.

Including math.h does not remove the need to link in the math library, it provides the declarations of the functions to the compiler, allowing it to check that the module using the functions is passing the correct parameters and the return type is assigned to a compatible variable.

The actual function is then linked in at the linking phase or the load phase.

Dynamic linking is the norm, in which case the link phase does not actually include the functions in the resulting binaries, but it does check that they are present in the linked libraries. I believe it does include some information in the binary indicating which libraries contain the relevant functions, but I wouldn't be confident of that. Check for yourself if you wish to be sure. If static linking is used, the relevant modules from the library are actually included in the code that is generated. Either way the -lm flag is still required.

Neil


Top    Back