Webinar: Top 10 Bug-Killing Coding Standard Rules

Webinar: Top 10 Bug-Killing Coding Standard Rules

Top 10 Bug-Killing Coding Standard Rules | Dan
Smith Thanks Michael and thank you Jennifer as well.
Before we get into the actual 10 Coding Standard Rules that we are going to recommend here
let’s talk briefly about why to adopt a coding standard. Certainly one of the reasons to
adopt the coding standard is to improve the readability of the code, to make the code
more consistent. Particularly, if you are working in a large development organization
it’s nice to have one style, one look and feel for the code. It makes it more readable,
more maintainable, we can probably all agree on that. We’ve probably also seen the justification
for portability, in other words having a coding standard, which focuses on removing portability
issues can make your code more portable down the road when the hardware changes etcetera.
However, that said probably the best reason to have a coding standard is to keep bugs
out of your system whether it’s during the initial development process or during the
maintenance process. Each of these 10 Coding Standard Rules that
we are going to talk about today is focused entirely on keeping bugs out of your system
because we all know how difficult it is to debug code. Slide 9: Where Bugs Come From So as I just mentioned one of the primary
reasons for having a good coding standard is to keep bugs out of your system. So, let’s
talk briefly about where bugs come from in the first place. We can all agree that there
are bugs in compilers, there are silicon errata but by far and away the majority of bugs in
a system are introduced by us the developers. And let’s not forget that most of the time
somebody else is probably going to be the person who takes over and maintains our code. When we are writing code we are making assumptions
about the underlying platform, about future developers and their capabilities etcetera.
All sorts of things we are not even really aware of and these assumptions are often undocumented.
So there is an opportunity for disconnect between the original programmer and how he
or she wrote the code and the person who comes along next who has to maintain the code. We strongly encourage you any time you find
yourself making assumptions to document these very deliberately and comments in the code.
That’s not one of the 10 rules we are going to talk about today, but we want to mention
it because this can help overcome the disconnect that can happen between the original developer
and the next person who comes along to change the code. Slide 10: MISRA-C Guidelines No talk on an embedded C coding standard would
be complete without mentioning the MISRA-C coding guidelines. The MISRA-C guidelines
came out of the automotive industry precipitated by the need to move from assembly language
to C. Let’s face it, we all love the C program language, but it is a dangerous language indeed. MISRA-C has become the standard for embedded
C programming and essentially all safety related industries such as medical devices, industrial
controls, avionics you name it. I am sure there are people listening today who use the
MISRA guidelines on a daily basis. MISRA-C defines a subset of the C programming
language that’s designed to increase the safety and reliability of code. Now, the MISRA
guidelines are not a coding standard per se, it’s a set of rules. For each rule a rationale
is provided and this really important because as long as a rationale is provided the rule
is more likely to be followed because the engineers are given a reason for it, they
feel that the rule is not arbitrary or dictated, but they actually understand why the rule
is in place. So, even if you are not in automotive, even if you are not doing anything that’s
safety critical the MISRA rules can still benefit your software project. So, take a
look at the rules and adopt and incorporate those to make sense for your project. Slide 11: Coding Standard Enforcement In Barr Group, we work with a lot of companies
and a lot of different code bases and probably about half the companies and projects we work
with have a coding standard. However, when we get the code and we look at the coding
standard the two don’t seem to work together. In other words the code does not often seem
to resemble the coding standard and we ask ourselves well how does this happen, what’s
going on here and generally what happens is that it comes down to enforcement. So, good
coding rules have to be enforceable and we found that objective rules tend to be more
enforceable. By objective, I mean rules that are not subject
to interpretation, rules that can be enforced automatically by a tool for example. Lastly, the coding standard has to be embraced
and adopted by every member of the team. There can’t be exceptions for this developer,
that developer in fact any deviations from the coding standard need to be documented
and they should also be very rare. Slide 12: Rule #1 Always Use Braces Okay, on to our first rule, rule number 1,
which states to always use braces. There are certain key words in the C programming language
such as for, while, if, else etcetera; which are followed by a statement to be executed.
The way the language is designed, this can either be a single statement such as an assignment
or a function call or what have you or it could be a compound statement, which is one
or more statements surrounded by braces. The way the language is designed if you only
have a single statement or even an empty statement following an if, while, else etcetera the
language does not require you to use braces. So many developers don’t use braces for
a single statement, but almost always this is a disaster waiting to happen. First of
all lack of braces can make it more confusing for others to come along to maintain your
code. This is somewhat subjective, so if that’s not enough to convince you to always use braces I will give a couple more reasons that deal directly with code maintenance, so let’s go look at
some code. Slide 13: Always Braces Example Code Okay, so here we have code. I think we can
all agree that the way this code reads when foo=5 we are going to call bar, so we are
going to call bar conditionally and then we are going to call the function always run
all the time regardless of the value of foo. Now let’s say it’s late at night you are debugging
and you need to make a change and you are thinking that call to bar is causing a problem.
So, just temporarily you want to comment out the call to bar. So you go ahead and put 2
forward slashes in front of it and you run your code and you are testing now. Well what’s going to happen is that now always
run is going to be called not all the time but conditionally based on the value of foo,
only when foo=5. This is almost certainly not what you wanted, you just wanted to comment
out the call to bar, but you did not want to affect how and when always run is called. So that’s one little surprise you are going to run into because there are not braces surrounding
the call to bar. Now let’s approach it from the other side
where we want to add in code. So, now when foo=5 we want to call not only bar, but
we also want to call function fred. Well again because we didn’t put the call to bar inside
2 braces, now what’s actually going to happen the way this code reads is that when foo=5
we are going to call bar, but we are actually going to call fred unconditionally all the
time just like always run in spite of how the code is formatted. So we can see just by surrounding the call
to bar in braces, it makes the code easier to maintain whether you are removing code
or adding code and whether it’s you maintaining the code or somebody else who comes along
later. Slide 14: Always Braces Example Code So here we have two examples of using the
braces even when it’s not strictly necessary. Here we have a single function call to bar
inside the conditional. This allows us to add code or remove code inside the braces
and the behavior will be exactly what we expect. And the second example here there is effectively
a null statement, an empty statement that gets executed while the timer is not expired,
but that’s again exactly what we want and we have a nice expressive comment there, so
that the next person who comes along knows exactly what we are doing in this code. Slide 15: Rule #2 Whenever Possible “const” Okay, on to our second rule, rule number 2,
which states to use the const keyword whenever possible as much as possible. Here on this
slide we list four different opportunities for using it. There are certainly other cases
where you would want to use it as well. What I want to mention though, however, is that
for embedded programmers as const is particularly important because any object that is const,
anything that is not going to be modified at runtime could be placed by your development
toolset into your ROM section and especially if you are working on a resource-constrained
system on a small microcontroller typically your ROM, your flash is a lot more plentiful
than your RAM. Another thing I want to point out by using
const is that it catches problems at compile time. So any attempt to write to a field of
a structure or an object that’s marked as const will be caught at compile time as opposed
to at runtime. And I think we all know anything you can catch at compile time, at build time
instead of a run time that’s a win. Slide 16: Maximize-const Example Code So let’s look at a few examples very quickly.
So, here we have a couple of objects gp_model_name, which is a pointer to a constant care, it’s
really a pointer to a string and there is no reason for this string to be modified at
runtime this is the products name. Similarly here we have a build number, it’s to find
it’s a constant integer. It’s initialized at build time and it should not be modified
at runtime. The next example function parameters that
must not be modified. So here we have strncpy, a function many of you are familiar with.
We want to copy from the source to the destination. So, obviously there is no reason that anybody
should be writing to the region that source is pointing to. So it’s marked as a pointer
to a constant character. Lastly and the final example we define an
object called heap size of type size_t, initialize it to 8192 presumably that’s going to be
the size of our memory heap that we are going to use at runtime. So, by declaring it as
constant in an object of type size_t, we have to type safety; however, we are not using
that preprocessor pound to find macro. There are some examples, some cases where
you still have to use a pound to find preprocessor macro, for example a case label and a switch
statement or the size of an array. In C++ it’s a little bit different, but in C you
can’t get away with using a constant object for that you still need to use the preprocessor
macro. Slide 17: Rule #3 Whenever Possible “static” Okay, moving on rule number 3, which states
whenever possible use the static keyword. So, the static keyword should be used to declare
all functions and variables or objects that don’t need to be visible or accessible outside
of the module the source file, the translation unit in which they are declared. The whole
point of this is encapsulation. This is all about localizing data and functions to provide
better encapsulation. By preventing modules from accessing data or functions that they
shouldn’t have access to, you make the software more maintainable and less brittle. For example, you might have a timer driver,
timer.c or something like that. You don’t necessarily want all the variables and all
the functions in that module to be accessible from the outside world. The nice thing about
static is that it’s enforced by the toolset during a build. So, if somebody tries to reference
something that they don’t have access to your build will fail. Again the nice thing about this just like
the const keyword is that you will fail at build time as opposed to at runtime. The upshot
of this is that makes your code more maintainable by a limiting visibility and access to the
outside world. Slide 18: Maximize static Example Code Okay, so let’s look at some code here. Here
we have a file timer.c the first thing we are going to do is include our associated
header file timer.h many of you probably implement your code like this. So timer.h is what we
will expose the public aspects of this file. So not everything in this file, not every
function and not every object is going to be exposed to the outside world. So here we have a variable called g_next_timeout
it’s a unit32, but it’s declared to static and what that means is that no one outside
of timer.c will be able to see this object. So, this is an implementation detail in your
timer driver that no one except for the actual implementation needs to access. We also have a function called add_timer_to_active_list,
this declared to static. So this is a helper function, a function that the outside world
cannot call this is not part of the API, perhaps the API is something like start timer and
then this helper function is used as part of the implementation, so perhaps we have
a linked list of timers. There is no reason that the outside world needs to care about
the implementation. Therefore, we make this function static preventing anybody in the
outside from ever calling this function directly. Slide 19: Rule #4 Whenever Necessary “volatile” Okay, on to rule number 4, which states whenever
necessary use the volatile keyword. There are few different use cases for the volatile keyword. We will go through 3 of these right here right now. The first is when you have a global variable
or an object that’s shared between an interrupt service routine and non-interrupt code, so
for example if you have a foreground/background architecture where you have interrupts running
in the foreground communicating by writing things to variables that are swept up by your
background that’s a perfect example of where those objects, those variables need to be
declared as volatile. Second example is if you have a variable where
2 or more tasks are communicating by sharing that variable again not the way you generally
want to write your code, but if you do have such a model those variables, those objects
need to be declared as volatile. The third example and the example that’s
probably most familiar to those of us who know the volatile keyword is when you have
hardware. So you have got memory-mapped I/O and you are writing to that hardware through
a structure overlay or a pointer that needs to be declared as volatile. Otherwise your
compiler and your optimizer are going to play some games and it might actually cause your
code not to work. Just a quick interesting side note here, it’s our experience that only
about half of embedded developers even know about or understand the volatile keyword. Slide 20: Optimization: Redundant Reads Let’s look at a code example. Here we have a hardware peripheral, that”s a timer, that”s memory- mapped and it has not been declared as volatile. You guys have all seen code like this before. First we reset the count to zero,
we start the timer and then we wait for it to count up to 100. Remember I said that the
timer peripheral is not been declared as volatile. So the compiler C’s count written to zero
and then it never sees it changed again. So as far as the compiler is concerned timer.count
will always be zero. So the compiler doing its very best effort to remove code, to make
your code smaller and faster, so what the compiler is going to do it’s going to say
hey in that while loop I don’t need to keep reading from timer.count it’s always going
to be zero. So, I am just going to turn that while zero is less than 100, I am just going
to turn that into a while 1. It’s a win, win. Smaller code, faster execution time, the problem
is it’s actually not going to go read your timer peripheral each time through that while
loop, so it’s going to get stuck there forever. Slide 21: Optimization: Unnecessary Writes Now let’s look at another example of hardware
not being declared as volatile. Except this time is that are reading from the hardware,
we are going to be writing to the hardware. So here we have the hardware peripherals called
led_reg and presumably the way this works is setting a bit low in the register turns
on the corresponding LED. So, this first line of code presumably we’re turning on the right most LED, okay indicating a patient is dying. Then we have a bunch of other code
that does not read from LED register and then we have a line of code that says LED register=FF. So again what the compiler is going to do
and it’s very best effort to do a good job for you and to make your code as small and
fast as possible it’s going to say if he wrote FE up there and then he never read from it
and then he wrote FF so I can just go ahead and do that final write to FF and no one is
going to be the wiser and I save it as that’s CPU cycles and code space. Awesome, it’s a
win-win right. So we’re never are going to see that LED
turn on indicating that the patient is dying that right operation was optimized away from
the compiler and it had every right to do that because LED register was not declared
as volatile. Slide 22: More on “volatile” So, just a few more words on the volatile
keyword here; so often times what happens is as you are developing code and you are
getting near the end of a project you begin to run out of memory or you begin to run out
of “CPU cycles”. So what’s the first thing you often do, you turn on the optimizer to try to get back some memory, to try to get back some CPU cycles. What often happens is, once the optimizer
is enabled the code stops working. Most developers will immediately say, “Ah, I just found
a bug in the compilers optimizers,” but very often that’s not the case. Typically
it’s a missing volatile keyword either on your access to hardware or to a shared variable.
So, the first thing we recommend you do when you turn on the optimizer and something breaks
is look for missing uses of volatile when you should be. So these examples I showed
you a couple of slides ago, these recommendations went to use volatile. Another thing is that the volatile keyword
is essentially unused outside of embedded software. So this is a very good question
to ask when you are interviewing people. One other notable uses of volatile the keyword
that I will point is when you are doing security related functions and you have sensitive data
in memory such as plain text that’s needs to be encrypted or encryption keys or things
like that. What often happens is that these are local and when you are done with them
you want to wipe them, you want to overwrite them to zero because as we all know when you
return from a function that information is still sitting there in the stack even though
it’s not supposed to be accessed. Well, if you go to wipe these keys or this
plain text on your stack at the end of a routine, the compiler might say well after this person
overwrites this with zeros no one ever reads back from this, so I am just going to optimize
out that that wiping that overwriting function not understanding the security sensitive information.
By marking those objects as volatile you are guaranteed that any write operations, specifically
the wiping is actually going to take place. Slide 23: Volatile Usage Example Code So let’s just look at a few examples where
we are using the volatile keyword in the way it should be used. So in the first example
here we have a global variable called g_state and again we all know the global variables
are not good and we don”t want to use them, but in this example we have one. We are initializing
it to SYSTEM_STARTUP and it’s marked as volatile and that”s means in any task or in any thread
or in any interrupt, any access to g_state, any read or any write will be performed, it
will not be optimized away. The next example we have a structure overlay
called my_fpga_t and we are declaring a pointer it’s called p_timer and it’s a constant pointer
to a volatile my_fpga object. So the pointer itself isn”t going to change what it points
to, but what it points to is volatile to a piece of hardware presumably over in an FPGA.
It’s very important that we mark hardware accesses as volatile. And then lastly we have an example of an array
presumably local called plaintext, size MAX_PLAINTEXT and it’s marked as volatile that means any
wiping that we are going to do at the end of the routine where this is declared will
actually be performed. Slide 24: Rule #5 Don”t Disable Code with
Comments On to rule number 5 which says, “don’t
disable code by commenting it out.” What we are saying here is if you need to disable
code for example you are testing, you are debugging use the preprocessors conditional
compilation feature. The thing is nested comments are not part of the C standard. The preprocessor’s
conditional compilation functionality is designed to nest properly, so that is going to work
on any toolset, on any compiler, on any platform whereas nested comments you might move the
code to a different platform and it’s not going to work anymore and that’s because
the support is not part of the C standard. If you have to make experimental code changes,
make a branch in your version control system that’s what it’s there for. Don’t leave
commented out code there in the code base for the next person to come along, that’s
dead code. Remember, commented out code is not compiled, so it could be that that code
has been there for 10 years and it wouldn’t even compile anymore. Maybe the dependencies
have changed, maybe it was even for different hardware platform, but the next person who
comes along is going to look at that code, scratch his or her head and say, “Hmm, I
wonder if this is important.” But longer that code links in your system the more it
rots the more it becomes out of date and the more potential it has to cause problems. So
get rid of that code keep it in your version control, but get rid of it so that it’s not
polluting the minds and code base of everyone who is working on it. Slide 25: Commented out Code Example So let’s look at some code that’s been commented
out here in the DON’T section here. Originally we have 3 lines of code incrementing A and
then a comment and then incrementing B. Now someone comes along and they just want to
comment out or disable this big block of code. So they wrap this thing in your classic C
comment with a /* and then after at the end of all that code that they want to disable
they put a */ thinking that they are effectively disabling all of that code. Well because you have got this nested comment
in here it’s very possible that the end of the comment where we see nested comment that
that’s /* that that’s actually going to end the comment that were started where we
see outer comment in red. And so we are going to comment out the a=a + 1, but the b=b
+ 1 is not going to be commented out and of course that last red */ is probably going
to give you a compiler error. So, this is a code that will work on one compiler, you
go to a different compiler it might behave differently. So our recommendation again using the preprocessor
#if 0 to temporarily disable code. As I mentioned before please don’t check in code like this
in your version control. This is only why you are developing and debugging but then
eventually what you check in should not have this in there at all. It’s going to be confusing
to people and it’s another opportunity for code to be unintentionally reactivated by
someone with good intentions who just doesn’t understand that that code needs to be disabled.
Remove it from your source code check it into your version control you are good to go. Slide 26: Rule #6 Fixed-width Data Types Okay rule number 6, which is about the usage
of fixed-width data types. So an embedded programming sometimes you really need to specify
the specific width of an object. Perfect example is when you are doing memory-mapped I/O and
you have a structure overlay and certain registers in your hardware are 16 bits, some are 8 bits,
some might be 32 bits. This is defined by your hardware and when you are defining a
structure that you are going to overlay you need to make sure that the data types that
you are using match up exactly against the hardware registers. And another reason for using fixed-width data
types, sometimes you know the size and the range of the objects that you are dealing
with and if you use a type such as int that might work on the current platform you are
using, but then if you port that code to a different platform where now an integer is
no longer 16 bits perhaps now it’s 32 bits and now that code is going to break. So our
recommendation is to use C99’s fixed width data types for signed and unsigned values
and I am going to show you on the next slide what those are. And one of the upshots of
this is that in general you are not going to want to use things like int, long, short,
care etcetera because these are not portable. The width of these types varies from platform
to platform. Slide 27: Recommended Fixed width Type Names So let’s look at the types that are provided
for you in C99. The header file you are going to want to include is standard int.h, stdint.h,
is provided here for you. Notice that we have both signed and unsigned types, as small as
8 bits and as large as 64 bits. Now notice that this is independent of the underlying
architecture so whether you are using a little 8 bit microcontroller or a 32 or 64 bit microcontroller,
all of these types are available for you. How they are implemented on your processor
platform that’s a different story. If you are unfortunate enough to not have
a C99 development toolset, what we advise is that you create a header file by using
typedefs create the same types, so that your code looks as if it’s written for C99. And
then when you move over to a C99 development platform your code will still work and run
just as it did before. Slide 28: Rule #7 Bit-wise Operators Rule number 7, basically rule number 7 all
comes down to this, the advice, don’t use bit-wise operators on signed data. A corollary to this is anytime you have an integer literal, a decimal constant and you
want it to be treated as an unsigned value put the U suffix at the end. Most people rely
on the fact that their underlying architecture is probably a 2’s complement architecture,
but the C standard does not specify that and there is no guarantee of that, but bit-wise
operations rely on those assumptions and that’s why bit-wise operators on signed integers
or signed data are not supported. Let me show you some examples and you will see the kind
of trouble you can get into. Slide 29: No Bit-wise Signed Example Code So here in the first example we have something
called signed data, it’s a signed 8 bit value when you are sized to get to -4 no problem
with that and then almost certainly the developer in the next line where he or she is shifting
sign data right by 1 is trying to divide it by 2. But you don’t need to try to outsmart
the compiler and tell it to shift. Just tell it divide by 2 and it will figure out the
best way to do that. A right shift of a signed value is implementation defined. So what’s
going to happen is not necessarily going to be portable across different architectures.
You have no reason to expect that that right shift is going to actually divide that by
two. In the second example, here we have a value
of 32 bit signed value, we are initializing it to -100 and then we are less shifting it
by 1. Presumably the intention is to multiply it by 2, but this is in fact undefined behavior,
all bits are off as soon as you venture into undefined behavior. In the last example, here we have an 8 bit
unsigned value we are calling it max_unsigned and it’s ~ 0. Well we all know what 0 looks
like, ~ 0 it’s going to flip all the bits and that’s going to give us the maximum
unsigned value, it’s 255 because it’s 8 bits. Now someone comes along and wants to do the
same thing for an 8 bit signed value. So they do ~ 0 as well. Well that’s actually not
going to represent the maximum signed value which will be +127, it’s actually going to
give you -1 when all the bits are set in the 2’s complement notation. So these are all
examples of how performing a bit-wise operation on signed data can burn you. Slide 30: Rule #8 Don’t Mix Signed & Unsigned This next rule, rule number 8 is one of my
favorites. It’s one of my favorites because this is a rule that I find is eye-opening
even for experienced developers. The rule is to not mix signed and unsigned values in
a comparison or expression. The reason for that is that C has very, very complex integer
conversion rules part of which is what’s called integer promotion rules and mixing signed
and unsigned values in the same expression or a comparison can lead as a very unexpected
behavior. And the problem with this is things can work for a long period of time because
you have never actually mixed values where you are going to see this. Sometimes this is the case where bugs can
actually even escape to the field, they pass all tests, they get out to the field and then
something very unexpected happens. So let me show you some code and let me show you
how this actually works and it might be an eye-opening for a lot of you. Slide 31: No Mix Signed Example Code So here is a very simple example that illustrates
exactly the kind of hazard that you can run into when you mix signed and unsigned in the
same expression. We have an int S initialized to -9; we have an unsigned int U initialized
to 6. Now if you ask any 3rd grader what is -9 + 6 that child is going to tell you it’s
-3. So, we would expect because -3 is less than 4 that we would go into the if clause
there. But what actually happens is we are going to go into the else clause and that’s
because S, the signed integer, is promoted to an unsigned int before it’s added to U. Slide 32: Rule #9 Favor Inline Over Macros Okay, our second last rule, rule number 9
states to favor inline functions over macros. A lot of people don’t realize that as of
C99 inline functions are part of the C standard. Now it’s important to understand as we are
noting here that the inline keyword is not a command to the compiler, it’s more of a
hint or a suggestion just because you put inline it doesn’t mean that the compiler
is actually going to inline the function and in fact if something people are not often
aware of is that you can also have functions, which do not have the inline keyword that
the compiler if you turn on the optimizer that the compiler might actually inline anyways;
but it is a hint, it’s a suggestion to the compiler. So, let’s take a look at some code
and we will show you how this can actually save you from getting into trouble. Slide 33: Inline vs. Macros Example Code So here we have an example, we have a macro
called square, it takes a single parameter A, notice that there is no type for A because
square is a macro, it’s not a function. Macros have no concept of type checking, macros are
handled by your preprocessor not by your compiler. So presumably the intention is whenever you
use this square macro the intention is for that to expand into an expression, which is
the square of the parameter that’s passed; but now let’s say you pass ++I, let’s say
you initialize I=5, int I=5 and that you call square with ++I. Well you can look here at the macro expansion
and you can guess pretty quickly what’s going to happen. I is going to be pre-incremented
twice. So you are actually going to evaluate 6 times 7 again assuming I was initialized
to 5 before we called square, instead of which you would expect which is a value of 36, 6
times 6 it’s actually going to evaluate to 6 times 7 because that pre-increment operator
is going to evaluated twice that side effect. Now let’s look at a similar implementation
by using inline functions. So again, here now we have type checking, so the input parameter
is a uint16, obviously for squaring it we need the return value to be a uint32. Someone,
so someone is calling square with a value that won’t fit inside a uint16 your compiler
is going to give you a warning, or at least the static analysis tool will. So now we have type checking, similarly if
you call this inline function square with ++I when I is set to 5 you are going to invoke
this function, it’s going to be passed to value of 6 and you are going to return 6 times
6 which is a value of 36, which is exactly what you expect. So this illustrates the fact
that inline functions give you type safety and safety from side effects. Slide 34: Rule #10 One Variable Declaration
Per Line Okay, last but certainly not least rule number
10, our final rule is to give each variable declaration it’s own line in your source code.
I mean after all each of these little variables is going to work so hard on your behalf during
the programs execution. The least you can do is give it’s own line in the source file,
all right. The main reason for this is to improve the readability of the code. The compilation
process is not going to go any slower. The code is not going to be any bigger or run
any slower if you give each variable it’s own line, but now the code is going to be
a lot more readable. Case in point, let’s look at the last line
of code here. If I want to ask everybody what is the type of variable Y, I am sure some
people would say pointer to character and some people would say character. It turns
out that the answer is character that asterisk binds to the X, but by putting these two variable
declarations on their own line the code is unambiguous. So all we are saying is write
your code, thinking about the person who comes after you who might now have the same strong
command of the C programming language that you do. Slide 35: Key Takeaways So as we discussed the coding style of the
original programmer will influence not only the bugs introduced by him or her, but also
this can have an influence on bugs that are introduced later on during the maintenance
phase. And then lastly a coding standard is only as good as its enforcement, so make sure
that your coding standard rules are enforceable and that you process mandates that the coding
standard is actually enforced. So, I hope that you found these 10 rules to
be valuable if you have a coding standard you might want to integrate some of these
rules into your own coding standard. If you don’t have a coding standard perhaps these
10 rules can be the basis for a coding standard that you begin to use in your own development
process. So that’s it. Thank you very much for joining
us and we look forward to seeing you next time. I am now going to turn the presentation
back over to Jennifer.

4 thoughts to “Webinar: Top 10 Bug-Killing Coding Standard Rules”

  1. Very nice presentation, filled with awsome tips! Though I would like to hear more about mixed signal ingeters operations. Wether I could use casts or other workarounds, and more examples.

Leave a Reply

Your email address will not be published. Required fields are marked *