Lint is a standard tool on most Linux or Unix development systems. In the PC realm, however, you often have to go out and buy lint, or find a free or shareware version. If you do buy lint, rest assured it will likely be the best money you have ever spent in your embedded career. Incidentally, you may be wondering how well lint handles all those nasty little compiler extensions that are so common in embedded development.
This is an area where the commercial programs outshine the free and shareware offerings. In particular, some versions of lint allow considerable customization of lint's rules, such that all those extensions are correctly handled. In some cases, the compiler definitions are even supplied by the lint vendor. In others, you may be able to get them from the compiler vendor.
So, for all the neophytes out there, get yourself a copy of lint, and use it. If nothing else, your boss will be impressed with the maturity of your code. For all the experienced hacks who aren't using lint--watch out!
The new guys who are using it might show you up. Wikipedia - Lint. Darwin, Ian F. Checking C Programs with Lint. Sebastopol, CA: O'Reilly, This article was published in the May issue of Embedded Systems Programming. If you wish to cite the article in your own work, you may find the following MLA-style information helpful:. Embedded Software Boot Camp.
Embedded Security Boot Camp. Debugging Embedded Software on the Target. Source Code Review Services. Reverse Engineering Services. Barr Group's logo is a U. Skip to main content. See for example. As you can see by referring to the page by Martinec, if snprintf had been a good-enough solution for Lynx, and I had chosen to not write one specially for porting applications, I could have waited a year or two and gotten someone else to write it.
While not suitable for use by a portable program, the asprintf function in the GNU C library was interesting because it showed that a version of sprintf was possible with a dynamically allocated output buffer. Solaris developers were slower here finally appearing in Solaris 11 twelve years later :. A number of new routines are included in the Oracle Solaris C library to improve familiarity with Linux and BSD operating systems and help reduce the time and cost associated with porting applications to Oracle Solaris 11 Express.
Examples of new routines include asprintf , vsprintf , getline , strdupa and strndup. The latter creates a new string, the former appends to a string. Lynx uses both:. The two are closely related: HTSprintf0 is a special case of HTSprintf , since it sets the destination to an empty buffer and calls the latter function.
From the counts, you can see that lynx uses the more general form most of the time. If lynx is built on a machine which has vasprintf , it will use that function. One reason is that the NLS support message files may use an obscure feature for plurals:. Rather than double the amount of work, I chose to use vasprintf , which is available with Linux and the BSDs. On other platforms, lynx uses the easily ported code:. Compiler warnings help show when the format cannot handle a given data type and the resulting printout will be incorrect.
Compiler warnings come into play in lynx with a couple of troublesome data types:. This data type is associated with file size , because the lseek function uses an offset with this type when positioning a file descriptor within a file. The original lynx developers decided that was the same as long and passed the filesize around — and printed it — with a format for long.
A cast is needed, as well as definitions for printing format. The configure script can easily determine the size of these types, but getting the compiler to tell which are the preferred names for a given size is harder. Again, I solved this with a thicket of ifdef's.
Generated code should compile with as few or fewer warnings than normal source-code. For both byacc and reflex I have done this. In a recent July episode I made some build-fixes to make that work. But as I reported in Debian , I preferred to not use that tool because it added more than 25, lines of warnings to my build-logs. I started writing build-scripts when I started working on programs that took more than a minute or two to compile. For example, in I wrote this build-x script:.
Later, I found that it helped to construct build-scripts which knew about the specific compilers available on different machines — so that I could verify that my programs built correctly with each compiler.
I collected logs from these builds, starting in both ncurses and lynx. There were a few exceptions: as part of my release process for lynx I kept the logfile from a test-build on the server at ISC which hosted lynx. I started that in December But for the other programs: my versioned archives for ncurses build-logs start in July Other programs followed, as well as more elaborate and systematic build-scripts. For an overview of those, see my discussion of sample build-scripts.
As of September , I have scripts for building programs, in various configurations. I collect the logs from these, and compare against the previous build — and look for new problems such as compiler warnings. I track build-logs to avoid introducing problems for others who build my programs either packagers or individual developers.
None of my machines run continuously, and a build-server would make little sense because I have to test on many platforms , so a set of scripts provides a workable solution. Packagers give the most immediate feedback when there is a problem building ncurses or xterm. They typically use a particular set of machines, with build-servers. Packaging and systematic builds go together. Also until around the time that I got involved in packaging , Linux packagers did not as a rule provide source repositories for their packaging scripts from which one could get useful information about the reasons for package changes.
The BSD ports on the other hand provide historical information but are strongly dependent on the structure within which a port is built. I began packaging all of my programs in when I started using virtual machines for the bulk of my development. I wrote and am still writing a set of scripts to manage this. Rather than adding onto an existing upstream source and adding version information to that source, my packaging scripts work within the existing structure and use my existing versioning scheme.
The unproto program was of course long unused. The build scripts actually invoke several scripts depending on the availability of packaging tools and cross-compilers.
Each produces a log file. As of September , I have 77 release scripts, including 22 which generate documentation for my website. I have not written scripts for everything: I have 14 programs in my to-do list for scripting. When I first used lint in , I was working with another developer. I found lint useful anyway.
It would tell me about cases where I made a typo, using fprintf where I meant printf , e. At the time I wrote the gcc-normal and gcc-strict scripts, I found a use for gcc solely for its warnings. I used gcc warnings to flag places where. Due to its lack of warranty, we did not use it for the end product.
As part of the process, I made the cron job send everyone on the development team a daily report of the diffstat. That was I stopped the email. Seeing that a few developers made a majority of the changes, I discussed the compiler warnings with those people. Some liked the idea. One developer, however, got up immediately and left the office when I sat down next to him.
When I caught up with him, he had not calmed down, saying:. So not everyone liked fixing compiler warnings. This developer was fairly productive, but liked to work alone in the evenings when others were not around. One morning I was chatting with another developer when I happened to notice a hole in the wall, perhaps inches in diameter.
I remarked that I hadn't seen that before. The person I was talking to remarked that the other developer had done it. He replied that the other wore boots. Enough said. During the last year or so that I was at the Software Productivity Consortium, I spent some time reviewing and suggesting improvements to programs that I found on the Internet.
One of those was gcc. That in particular had a lot of compiler warnings because the code ignored the difference between signed and unsigned values , but other parts of gcc needed work as well.
I sent a patch for gcc which fixed about 5, warnings to gcc's developers probably early Richard Stallman responded, a little oddly I thought: he asked what I wanted them to do with the patch. I replied that I wanted them to use it to improve the program.
I heard no more. If they did incorporate any of the fixes, there was no record of that in later versions. Expanding a little on my remarks here , quite a while ago, Richard Stallman sent a message to mailing list explaining that others found warnings useful, but that he did not. Likely that had some influence on the default compiler warnings as well as the choice of options which comprise -Wall :. In gcc The reason for the option being separate is easy to understand, given the context: this was only a few years after C had been standardized, and few programs had been converted to ANSI C.
Developers of complex tools have to keep in mind compatibility. Moving options between categories is guaranteed to break some people's build scripts. For instance, gcc also has. Needlessly turning on warnings that developers had earlier chosen to not use and stopping the compile as a result is not a way to maintain compatibility.
For more context on -Wall versus -Wstrict-prototypes it helps to read the entire section rather than selectively pick out text. The last paragraph in current documentation for -Wall for instance points out that -Wall is not comprehensive, and that ultimately the reason for inclusion was a matter of judgement as in the original documentation :. Note that some warning flags are not implied by -Wall. Some of them warn about constructions that users generally do not consider questionable, but which occasionally you might wish to check for; others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning.
Some of them are enabled by -Wextra but many of them must be enabled individually. As for whose judgement that was — it would be the original developers of gcc around Some of those were prompted by lint warnings.
Those he rejected as unnecessary. For example, one of the diffs would have begun like this:. Interestingly enough, gcc has nothing to say about that. Compiling execute. So there is something to be said, even without lint. After Brennan released mawk 1. I noticed this because one of the packagers made an inappropriate change involving byacc and mawk. Debian had accumulated 8 patches; I incorporated those and set about making the normal sort of improvements: compiler warnings, portability fixes and bug-reports.
One of the bug-reports dealt with gsub Debian Brennan had written this to recur each time it made a change. I made an initial fix to avoid the recursion in December , but it was slow. Returning to this after some time, I was in the middle of making a plan to deal with this in August when I received mail from Brennan. That lasted 5 weeks, ending because we were not in agreement regarding compiler warnings. Here is one of my replies:.
Also, Mike regarded the no-leaks code as unnecessary, proposing a change to remove it. His parting message in September was:. In August , Mike Brennan posted to comp. From the discussion above, the reader can see that the "in some cases, was wrong" refers to compiler warnings and checking for memory leaks. Because Brennan expressed no other concerns during five weeks, likely the entire sentence is focused on that one issue. For the record,. The Usenet thread X11, Xt, Xm and purify on comp.
Not all warnings are beneficial. When they are overdone, they are detrimental. Consider snprintf and its followups strlcpy , strlcat. In my first encounter with these in , it was to modify the names of the strlcpy function which I wrote in to avoid conflict with the latter one of several cases where BSD header files included non-standard functions without any ifdef's to avoid namespace pollution.
My function lowercases its argument. The OpenBSD function attempts to remedy the ills of the world by offering a better version of strncpy. Conveniently enough, there is an strncat variant. There are a few drawbacks to using the standard strncpy and strncat :. If the actual null-terminated source string is shorter than specified, strncpy appends null characters to fill the destination to the specified length.
If the actual source string is longer than specified, strncpy does not supply a terminating null character on the destination. While strncat is not documented with either of these problems, there is the possibility that users might expect it to be consistent with strncpy by using the total size of the destination buffer rather than the unused size of the destination.
But none of that was an original observation by the OpenBSD developers. Just from my own experience, while strcpy , etc. In the text editor vile vi like emacs , the strmalloc function equivalent to strdup dates from It has a replacement for strncpy fixing the string-terminator issue dating from However, starting with my changes for TBUFF in , vile has generally used dynamically allocated strings except for special cases such as buffer-names.
In the web browser lynx , it has used dynamically allocated strings since , with some holdouts for fixed buffers related to terminal width and filename length.
My work on HTSprintf starting in reduced those special cases. However — read this thread lynx-dev Lynx buffer mismanagement — to be reminded of the difference between work and criticism, constructive or otherwise. We plan to replace occurrences of strncpy and strncat with strlcpy and strlcat in OpenBSD where it is sensible to do so.
OpenBSD developers did not modify any of those calls in lynx. Rather, they played a minor role in reporting bugs and making small fixes. For instance, comparing the last labeled release 2. But 15 of those files are unrelated to fixes , but rather overlooking deleted files, removing the help-message from the configure script, OpenBSD-specific URLs, etc. Here is a diffstat for the files with fixes:. That is about 50 lines changed in a program with thousand lines of C code.
Finally lynx was removed from base to allow more frequent updates via OpenBSD ports see mailing list thread. According to the CVS history, those functions were added in , with substantial changes going into Later July after relicensing the replacements, these standard functions were modified to force the linker to warn about their use:.
The same was done later when incorporating these functions though on OpenBSD the wide-character functions are little used :.
On the other hand, there are no analogously improved versions of scanf or sscanf , etc. Frank - its a bad idea to follow what Linus recs; git doesn't scale to large repos and has other known problems. GoodPerson - it doesn't? Sign up or log in Sign up using Google. Sign up using Facebook.
Sign up using Email and Password. Post as a guest Name. Email Required, but never shown. The Overflow Blog. Podcast Making Agile work for data science. Stack Gives Back Featured on Meta. New post summary designs on greatest hits now, everywhere else eventually. Linked 0. Related Hot Network Questions. Question feed. Stack Overflow works best with JavaScript enabled.
Accept all cookies Customize settings.
0コメント