GCC Warning: implicit declaration of function 'puts' is invalid in C99 - macos

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.

You need to include stdio.h, i.e.
#include <stdio.h>
at the start to import the function definition.

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.

Related

Strange error message for isprint() using arm-none-eabi-gcc

I have the following code:
#include <ctype.h>
void myfn(void)
{
uint8_t any0 = 'c';
char any1 = 'c';
if (isprint(any0))
{
return;
}
if (isprint(any1))
{
return;
}
}
When I compile it with gcc for arm, I get the following error:
error: array subscript has type 'char' [-Werror=char-subscripts]
if (isprint(any1))
^
If I pass an unit8_t to isprint, the compiler is happy, but not if I pass it a char.
The prototype for isprint is:
int isprint(int c);
It expects an int as parameter, I give it a char.
I would expect it to complain about the type of the parameter, but not something unrelated as 'array subscript'.
The error goes away if I change the call to:
if (isprint((uint8_t)any1))
Is there something I have overlooked?
The compiler I use is:
GNU C (15:4.9.3+svn231177-1) version 4.9.3 20150529 (prerelease) (arm-none-eabi)
compiled by GNU C version 5.2.1 20151129, GMP version 6.1.0, MPFR version 3.1.3, MPC version 1.0.3
warning: MPFR header version 3.1.3 differs from library version 3.1.4.
Commandline options:
'-v' '-fshort-enums' '-specs=nosys.specs' '-specs=nano.specs'
'-mfloat-abi=soft' '-save-temps' '-Werror' '-Wpedantic' '-pedantic-errors' '-mthumb' '-fno-builtin' '-mcpu=cortex-m0' '-Wall' '-std=gnu99' '-ffunction-sections'
'-fdata-sections' '-fomit-frame-pointer' '-mabi=aapcs' '-fno-unroll-loops' '-ffast-math' '-ftree-vectorize' '-Og' '-g'
If I compile the same code with the gcc compiler for AVR /usr/bin/avr-gcc (using similar commandline options and I intentionally added option -Werror=char-subscripts), it doesn't complain about isprint. So it seems to be something related to the ARM compiler.
It turned out that the implementation of isprint for ARM is a macro and, more importantly, header file ctype.h contains the following comment:
These macros are intentionally written in a manner that will trigger
a gcc -Wall warning if the user mistakenly passes a 'char' instead of
an int containing an 'unsigned char'.
For AVR, header file ctype.h contains:
extern int isprint(int __c) __ATTR_CONST__;
This explains the difference in behaviour when compiling for AVR or for ARM.

gcc-4.8.2 doesn't link pthread

all.
Compiling simple stuff using the gcc toolchain for several years, today I ran against a curious phenomenon.
I installed Kubuntu 14.04 to a common desktop i686 machine with gcc 4.8.2 in it. But then, trying to build some well coded stuff pulled out from my local repository, I ran against tons of 'undefined reference to' messages. The code compiles, links und runs well under Ubuntu 11.04 / gcc 4.5.2.
I checked the linking process (by -Wl,--verbose to gcc), think it works. It finds all libraries I specify in the link command. An objdump -t myLib.so brings exactly the symbols I'd expect - but the linker doesn't see them.
Checking the pthread library also brings according symbols, except they are suffixed with some #GLIBC... stuff. Didn't check linker/loader tricks so far.
A sample like
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
static void *fooo (void *xxx) {
char *txt = (char*)xxx;
printf("My job is to print this :'%s'. Bye now!\n", txt);
return 0;
}
int main (int argc, char *argv[]) {
pthread_t thd;
pthread_create(&thd, NULL, fooo, "A POSIX thread");
sleep(1);
return 0;
}
runs very well on the old system just saying
gcc -l pthread fooo.c && ./a.out
but breaks at the linking step with 4.8.2.
Any idea would be very welcome.
.M
Thanks to sfrehse, JoachimPileborg et al!
Indeed, success depends on argument order. I knew this fact for static linking, but it is new in processing of shared objects with gcc.
Does someone know what the background of this improvement is? It breaks innumerable build processes, and I guess thousands of tomatoes are being made ready against gcc.gnu.org .....
.M

Mingw32 cross compile with c++11

How can I cross compile on Linux for Windows with code that uses C++11 features? So far I've attempted the following:
#include <stdio.h>
class foo
{
public:
const char* getstr() { return "hello world"; }
};
int main()
{
printf("Hello, World!\n");
foo f;
f.getstr();
auto q = f.getstr();
return 0;
}
This fails to build with:
i586-mingw32msvc-g++ cpp11_test.cpp
cpp11_test.cpp: In function ‘int main()’:
cpp11_test.cpp:15: error: ISO C++ forbids declaration of ‘q’ with no type
cpp11_test.cpp:15: error: invalid conversion from ‘const char*’ to ‘int’
No problem I thought, I just need the -std=c++11 option:
i586-mingw32msvc-g++ cpp11_test.cpp -std=c++11
cc1plus: error: unrecognized command line option "-std=c++11"
Still no luck, --version output is:
i586-mingw32msvc-g++ --version
i586-mingw32msvc-g++ (GCC) 4.2.1-sjlj (mingw32-2)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Is there another option to make this work? Or a new version? How would I get a new version if its not in the package manager, would I have to build a newer compiler from source using the host OS'es compiler?

CppUTest error with -std=c++11 on g++ 4.7.2

I've been using CppUTest with g++ 4.7.2 for a while now without problems. However, I've just flipped the -std=c++11 option on so I can start using std::unique_ptr and it fails immediately.
Even just compiling the main module:
#include <CppUTest/CommandLineTestRunner.h>
int main(int argc, char ** argv) {
return CommandLineTestRunner::RunAllTests(argc, argv);
}
fails with variations on:
In file included from /usr/include/CppUTest/TestHarness.h:77:0,
from /usr/include/CppUTest/CommandLineTestRunner.h:31,
from tests/testmain.cpp:15:
/usr/include/CppUTest/MemoryLeakWarningPlugin.h:56:53: error: declaration of ‘void* operator new(size_t) throw (std::bad_alloc)’ has a different exception specifier
In file included from /usr/include/c++/4.7/ext/new_allocator.h:34:0,
from /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h:34,
from /usr/include/c++/4.7/bits/allocator.h:48,
from /usr/include/c++/4.7/string:43,
from /usr/include/CppUTest/SimpleString.h:136,
from /usr/include/CppUTest/Utest.h:34,
from /usr/include/CppUTest/TestHarness.h:71,
from /usr/include/CppUTest/CommandLineTestRunner.h:31,
from tests/testmain.cpp:15:
/usr/include/c++/4.7/new:93:7: error: from previous declaration ‘void* operator new(std::size_t)’
Removing the -std=c++11 option makes everything work just fine again.
The CppUTest documentation makes some comments about the macros conflicting with overloaded new operators, and suggests #including the standard headers first, but I get this problem without including any headers at all, although it looks like CppUTest/CommandLineTestRunner.h is including <string> itself.
Anyone come across this before or know what the issue is?

Variable name 'xor' results in internal compiler error 'segmentation fault'!

Compiling this code
int main(int argc, char **argv)
{
int xor = 0;
}
via
g++ main.cpp
results in:
internal compiler error: Segmentation fault
with
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659).
Renaming the variable removes the error.
Question: Is gcc from Apple crap?
Any time your compiler segfaults, it's a bug. Your already reduced test case is a perfect candidate to be reported to GCC.
and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor and xor_eq are keywords which are enabled with -ansi or -foperator-names
you have one of those switches enabled?
check also out: this

Resources