This week's book giveaway is in the OO, Patterns, UML and Refactoring forum.
We're giving away four copies of Five Lines of Code and have Christian Clausen on-line!
See this thread for details.
Win a copy of Five Lines of Code this week in the OO, Patterns, UML and Refactoring forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Bear Bibeault
  • Ron McLeod
  • Jeanne Boyarsky
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Liutauras Vilda
  • Junilu Lacar
Saloon Keepers:
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • fred rosenberger
  • salvin francis
Bartenders:
  • Piet Souris
  • Frits Walraven
  • Carey Brown

Function sqrt undefined?

 
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So, I bought a copy of Modern C by Jens Gustedt (Manning 2019) (publisher's link). Brush up my C, I thought. Get it for $19.99 at a full 50% discount rather than paying $20  I am liking the book, but hit a problem when I found the exercise about the use of the ?: operator to allow negative square roots. If you have a copy with page numbers, it's on page 45, otherwise §4.4. This is what Gustedt writes:-I thought, that looks interesting; I must try it out, bit I am getting this sort of compiler error:-

gcc -o root_error root_error.c
/usr/bin/ld: /usr/lib/gcc/x86_64-redhat-linux/9/../../../../lib64/crt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
/usr/bin/ld: /tmp/ccVjsV0O.o: in function `sqrt_real':
root_error.c:(.text+0x2a): undefined reference to `sqrt'
/usr/bin/ld: root_error.c:(.text+0x48): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status

I could write a function prototype and main() and add #include <math.h>, but nothing seems to make that error about sqrt go away. What am I doing wrong? I am getting the same error on my Fedora31 laptop and our UbuntuMate 19.10 box at home
 
Saloon Keeper
Posts: 12133
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can you try compiling with -std=c11?
 
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
...and link with the math library ie. add -lm on the end of your gcc command line.

Regarding the main error, you're getting that because the compiler thinks you're compiling an executable, which must have a main() function which the OS calls when you run the executable. If you aren't creating an executable, add -c to the compiler command line.
 
John Matthews
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

me wrote:If you aren't creating an executable, add -c to the compiler command line.


So:

works for me, creating object file moose.o.
 
John Matthews
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

John Matthews wrote:Regarding the main error...


Sorry Campbell - only just spotted who posted the question. I'm guessing you know this bit
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you so much, and sorry for taking so long to reply. The -std=c11 (I also tried -std=c17) and -lm options got rid of that particular error about sqrt. Unfortunately, when I tried to add main(), I started getting other errors. I shall try playing with code and searching before coming back to ask again.
Is complex a keyword? Gustedt suggested that the tgmath.h file would contain everything necessary to run that code.
 
John Matthews
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:Is complex a keyword? Gustedt suggested that the tgmath.h file would contain everything necessary to run that code.


I'm only googling this myself, but it looks like tgmath.h #includes complex.h, which defines complex as a macro:
https://pubs.opengroup.org/onlinepubs/009695399/basedefs/complex.h.html

As complex.h is #included by tgmath.h then you shouldn't have to.
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The link you provided was very helpful; thank you. It also ways that tgmath.h should contain sqrt(double) too. It says something about ISO C in 2001. Don't know whether that means it was introduced after C99, but that would seem unlikely.
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So far, so good. It seems that -lm is the crucial tag; it enabled me to get a program to run and tell me √123.45E67.
Thank you. Shall try complex numbers soon.
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you again:Working nicely; root_real() and root_real2() seem to do the same thing, so I can use one or the other in line 17. I don't think they are really good function names, but I simply copied Gustedt's names.

campbell@xxxxx$ gcc root.c -lm
campbell@xxxxx$ ./a.out 123.45e67
The root of |1.2345e+69| is 3.51355e+34
Complex version of root = (3.51355e+34, 0i)
campbell@xxxxx$ ./a.out -123.45e67
The root of |-1.2345e+69| is 3.51355e+34
Negative number: Complex version of root = (0, 3.51355e+34i)


 
Stephan van Hulst
Saloon Keeper
Posts: 12133
258
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why do you have forward declarations when you can just move the main function to the bottom?
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I never knew you could do that. So I can get rid of the prototypes and move main() to the end? No sooner said that done.

If you have multiple functions in the same file, that does mean you have to declare them in a certain order, before they are used. If you declare prototypes for everything other than main(), you can have the functions in any order.
 
John Matthews
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
While we're in code review mode...

I would suggest changing:
to more like 'normal' C(++):
and of course you'd add a check for argc>1 before releasing it into the wild.
 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you. I wasn't planning to release that code, but since I have posted it here, it will have escaped like a 'flu virus anyway.
 
Saloon Keeper
Posts: 22259
151
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:I never knew you could do that. So I can get rid of the prototypes and move main() to the end? No sooner said that done.

If you have multiple functions in the same file, that does mean you have to declare them in a certain order, before they are used. If you declare prototypes for everything other than main(), you can have the functions in any order.



The C/C++ compiler parses from to bottom. A prototype is just a way of declaring the signature for a function without (yet) declaring its body so that other code can compile calls to that function correctly.

If you have defined the function before you call it then you don't need a prototype at all. And, for that matter, in the dialect I use for Arduino code, you generally don't need a prototype unless the method in question is declared static.

I like my main() method to be at the bottom anyway. So I can find it easily.

As to the main(int argc, char **argv) versus main(int argc, char *argv[]), they are ultimately the same definition, just different notation. You can declare char **argv and retrieve strtod(argv[1]) and that works just fine. I'm neutral on that one. I've done it both ways without spending much thought on it.
 
John Matthews
Ranch Hand
Posts: 191
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:As to the main(int argc, char **argv) versus main(int argc, char *argv[]), they are ultimately the same definition, just different notation.


Sure, it's probably the least of Campbell's problems But to me, *argv[] maps more closely to what the argument is, logically. That is, an array of strings, rather than just a pointer to a pointer. And argv[i] is how you normally access an array element.
 
Tim Holloway
Saloon Keeper
Posts: 22259
151
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

John Matthews wrote:And argv[i] is how you normally access an array element.



Well, until you've worked with C long enough that your brain cells begin to erode. Then you start coding stuff like (argv + 3).

Oh, and just to clarify on the sqrt undefined. The sqrt and trig and exponential functions are all (originally) implemented algorithmically, so you need to link in a math library in most implementations. Modern systems typically have an integral math processor do do much, if not all of that stuff in a single machine instruction, but way back when, I think they actually stole the Fortran math library in some implementations. Today, some systems allow multiple options, including native/versus library math (via a #pragma or compiler switch), and differing floating-point formats (IBM legacy mainframe FP is considerably different from IEEE form and if you want to faithfully re-create old NASA computations or something...)

 
Campbell Ritchie
Marshal
Posts: 69789
277
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Tim Holloway wrote:. . .  main(int argc, char **argv) versus main(int argc, char *argv[]), they are ultimately the same definition . . .

Yes, I knew that bit. But the other info you provided is very interesting (as it always is). Thank you.
 
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Problem:- Undefined reference to sqrt() in C Programming (or other mathematical functions) even includes math.h header

Windows user doesn’t get any warning and error but Linux/Unix user may get an undefined reference to sqrt. This is a linker error.

you will get an error like this:-
/tmp/ccstly0l.o: In function main':
test.c:(.text+0xb5): undefined reference tosqrt'
collect2: error: ld returned 1 exit status

This is a likely a linker error. The math library must be linked in when building the executable. So the only other reason we can see is a missing linking information. How to do this varies by environment, but in Linux/Unix, just add -lm to the command. We must link your code with the -lm option. If we are simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some information about your building process. To get rid of the problem undefined reference to sqrt in C, use below command to compile the program in place of the previous command.

For Solution visit:- Undefined Reference to sqrt in C Programming
 
If tomatoes are a fruit, then ketchup must be a jam. Taste this tiny ad:
Thread Boost feature
https://coderanch.com/t/674455/Thread-Boost-feature
    Bookmark Topic Watch Topic
  • New Topic