Does breaking rules in the (ANSI C) standard lead to or equate with buggy code?

To my understanding, standards are mainly for code portability between compilers, but I'm curious if some things in the standard that are only treated as warnings when not followed can cause software to actually fail, or if code is written that does not comply with the standard, and it compiles/executes where it needs to, can it usually be left alone?

Here's an example from the book Deep C Secrets (explanation about why that happens will be below everything). I'm not sure if this specific issue could cause possible mayhem (though it's an implicit cast to otherwise incompatible types), but it's the example that brought the question to my mind.

void foo (const char ** p) {}  int main (int argc, char ** argv) {     foo(argv);   //compiler says "line 5: warning: argument is incompatible with prototype"     return 0; } 

For the sake of the argument let's assume that the developer says "no big deal" and decides not to fix the warning since the code compiles (on their compiler). If this, hypothetically, could cause software to break why is it not an error? Or is a warning simply brought up because some other compiler may not support the assignment of const char ** = char **?



why it happens (or just check C FAQ):

On page 92 of this standard, the third possible constraint under (1) for simple assignments is that:

  • both operands are pointers to compatible types (with or without qualifications)
  • the type pointed to by the left operand has all the qualifiers (or more) than the type pointed to by the right operand

In this case, char ** and const char ** are both pointers to different unqualified types (pointers, one to a const char * and, a other to a char *).

Replay

To my understanding, standards are mainly for code portability between compilers

No, a programming language is a specification (written in some report in English with some formalizations), and that specification is (often) the standard. Some implementations (notably GCC compilers) accept (and document) useful extensions to the standard (such as statement-exprs & labels-as-values, and both are accepted by Clang too).

BTW ANSI C, a.k.a. C89, is an obsolete standard. You should follow C99 or perhaps C11.

Your compiler is right to warn you. And there is a simple fix: add a explicit cast for readability:

foo((const char**)argv);

the generated machine code is likely to be the same (on usual desktops or laptops), but the improved code is more readable (to you, or to the developer working on the same code base).

Notice that on some (weird) computers, a const data might be manipulated differently than a non-const one. For example, it might sit in some different address space, or different kind of memory (ROM vs RAM), or loaded with different instructions (e.g. on some Harvard architectures, where const data would sit in the instruction space).

Also const and restrict could enable more optimizations by the compiler (e.g. caching some loaded value in a register and reusing it more), so the generated code would be (sometimes) different, e.g. inside a more complex foo function.

A difficult notion when programming in C and in C++ is that of undefined behavior. Read Lattner's blog: What Every C Programmer Should Know About Undefined Behavior

I recommend to enable all warnings in your compiler (e.g. gcc -Wall -Wextra and perhaps even -Werror) and to improve the source code till you get no warnings. You'll gain a lot of developer's time following such discipline.

Category: c# Time: 2016-07-30 Views: 0

Related post

iOS development

Android development

Python development

JAVA development

Development language

PHP development

Ruby development

search

Front-end development

Database

development tools

Open Platform

Javascript development

.NET development

cloud computing

server

Copyright (C) avrocks.com, All Rights Reserved.

processed in 0.106 (s). 12 q(s)