31

I am beginning Zed Shaw's Learn C The Hard Way. I have downloaded XCode and the Command Line Tools. But when I compile the very first program:

int main(int argc, char *argv[]) {
     puts("Hello world."); 
     return 0;
 }

I get this warning:

ex1.c:2:1: warning: implicit declaration of function 'puts' is invalid in C99 [-Wimplicit-function-declaration]

The program does compile and execute correctly.

I'm using OSX 10.8.3. Entering 'gcc -v' gives:

Using built-in specs. Target: i686-apple-darwin11 Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1 Thread model: posix gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

Please help.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
grok12
  • 3,526
  • 6
  • 26
  • 27
  • The use of `int main(int argc, char *argv[])` when the arguments are unused is mildly silly; it should be `int main(void)` or even `int main()` instead. However, that's a debate for another day, probably. I note that GCC 5.x uses C11 (`-std=gnu11`) as the default compilation mode. `clang` (masquerading as `gcc`) uses C99. Both C99 and C11 require all functions (except `main()`) to be declared before they are used. – Jonathan Leffler Jan 01 '16 at 08:13

2 Answers2

51

You need to include stdio.h, i.e.

#include <stdio.h> 

at the start to import the function definition.

andrewmu
  • 14,276
  • 4
  • 39
  • 37
  • 2
    Also in lesson 2 Zed points out that you can get rid of the warning by using your include statement. So I'm crediting you with the correct answer. – grok12 Jun 01 '13 at 21:05
8

This "book" should be renamed to Learn To Hate C By Following Meaningless Examples That Are Blatantly Wrong.

The correct code in modern C would be plain and easy

#include <stdio.h>        // include the correct header

int main(void) {          // no need to repeat the argument mantra as they're not used
    puts("Hello world."); 
}                         // omit the return in main as it defaults to 0 anyway

While the original example

int main(int argc, char *argv[]) {
    puts("Hello world."); 
    return 0;
}

would have been just plain bad in 1989, in 1999 (that is 18 years prior to the writing of this answer, and almost as many years before the "book" was written) the C standard was revised. In the C99 revision, this kind of implicit function declaration was made illegal - and naturally it remains illegal in the current revision of the standard (C11). Thus using puts without #includeing the relevant header, i.e. prepending #include <stdio.h> (or declaring the puts function with int puts(const char*);) is a constraint error.

A constraint error is an error that must cause the compiler output a diagnostics message. Additionally such a program is considered an invalid program. However the peculiar thing about the C standard is that it allows a C compiler to also successfully compile an invalid program, though a compiler may as well reject it. Therefore, such an example is hardly a good starting point in a book that is supposed to teach C to beginners.

  • Is that link the official standard website/repository thingy? – Ungeheuer Sep 29 '17 at 04:05
  • @Ungeheuer no, unfortunately the [official standard](https://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents) costs money. This is the HTML version of the C11 final *draft* known by its working name **n1570**. – Antti Haapala -- Слава Україні Sep 29 '17 at 04:33
  • Thanks man. Last question. Does the linked website have previous standards? I don't see a way to navigate out of there. – Ungeheuer Sep 29 '17 at 05:05
  • Where does the Standard specify that any program that violates a constraint is an "invalid program"? An implementation is allowed to accept such a program or not, at its leisure, provided that it issues a diagnostic, and if there exists any conforming C implementation that accepts some particular blob of text, that blob of text is a conforming C program. – supercat Oct 22 '19 at 19:46