Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: How to find the problem in the object file Date: Thu, 26 Jan 2017 11:20:01 -0800 Organization: None to speak of Lines: 102 Message-ID: References: <23ab01a2-5220-42cb-80b2-20a2b4a35d5c@googlegroups.com> <2beebc58-3f8f-46c6-bd10-e2ec3cf87906@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="c4bbf5deaa7fb5ee9d54a2c91785016f"; logging-data="18461"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+lJlgc5h/DPJcRg2wyKREG" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:MARhI18AJ9h7oE7stCVgQYjpY4A= sha1:jLWojd/DFxR52v2eGoIQ9ELUEaQ= Xref: csiph.com comp.lang.c:102486 BartC writes: > On 26/01/2017 16:29, Keith Thompson wrote: >> BartC writes: [...] >>> Either your compiler is at fault or it's not set up properly to report >>> undeclared functions. And blame the language for allowing undeclared >>> functions to go undiagnosed by the compiler. >> >> Not necessarily. It's possible *and legal* to call a function >> that's been declared but not defined. For example, this source >> file / translation unit: >> >> void not_defined(void); >> >> int main(void) { >> not_defined(); >> } >> >> is perfectly valid, and a compiler has no reason to complain about >> it, but it won't *link* unless you provide the linker with something >> that defines the function. > > I was talking about compilation rather than linking. Why? Alla reported a link-time error, and she later said that she had been compiling the wrong source file(s). > If your example was: > > void not_defined(void); > > int main(void) { > notdefined(); > } then it would be an example of an entirely different problem. > then the compiler might not say anything about 'notdefined'. A C90 or non-conforming compiler might not say anything. A conforming C99 or C11 compiler will at least warn about it -- including the one Alla is using. > Then a > subsequent linker error would be ambiguous; has a module been omitted, > or is there a typo somewhere? That kind of problem is exactly why the language was changed in 1999 to disallow calls to undeclared functions (more precisely, to make such calls constraint violations, requiring a diagnostic). > But yes, there could be another type of error, I think less common, > where the name of the function in the declaration, and in the call, are > both misspelled the same way, and different from the actual definition. Again, not the problem Alla was asking about. > This would be a consequence of having to specify the function name at > least twice, once for the definition, again for the header. But every > time I'm brought up this as a possible source of errors, I've been > assured that it's not a problem... It usually isn't, but making it not a problem requires a little discipline. If the source file that *defines* a function has a #include for the header that *declares* it, then the compiler is able to diagnose any mismatch. Mistakes are of course possible, but they typically won't survive past the first attempt to compile the code. > Yet another kind of error that the latter can cause, possibly the most > serious, is where the name in the definition, and in the call (in > another module) are both spelled correctly, but the declaration in the > header is wrong. > > It will compile 'correctly', if the compiler doesn't report it, and it > will likely link properly, but the program can now crash if the caller > thinks the interface is different from it is. If the definition is not visible at the point of the call, and the visible declaration doesn't match the call, then that's a constraint violation (for C99 or later), requiring a diagnostic. > (On my gcc, it will give a warning about 'implicit declaration', which > it is possible can be missed if there are many other warnings or some > automatic build system is in use that doesn't abort on warnings.) One thing I dislike about gcc is that, by default, many constraint violation diagnostics are non-fatal warnings rather than fatal errors. But it's easy enough to invoke it with options that tell it to treat them as fatal errors, such as "-std=c11 -pedantic-errors". If you're getting so many warnings that you miss important ones, perhaps you code needs some cleanup. Or, if the excess warnings really are ones that can be safely ignored, you might try to find a way to disable them. Figuring out how to enable just the diagnostics you want, and how to make them fatal if desired, can be more difficult than it should be, but that's a compiler issue, not a language issue. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"