Skip to main content

C Std Coding

1.     INTRODUCTION

The goal of this standards document is to promote error free source code that is readable, usable, maintainable, and portable.  This guide defines a particular style, offers some justification for it, and presents examples where appropriate.

This guide is designed to serve as a reference for experienced library developers, and to acquaint new developers with the standard.

Each project may be segregated into functional phases, depending on customer requirements and development sequencing.

2.     2.    C Language

2.1     2.1 ANSI C

All code must be composed of valid ANSI C statements with no reliance on particular language constructs which might cause platform/compiler dependence.

3.     3.    Naming conventions

3.1     3.1 Program files

A 8.3 character file-name format can be used to name all program files.  Program files include:

Source files
Header files

3.1.1     3.1.1           Naming source files

The initial 8 characters for source files can  be made up as follows:
<application name><module name>

Application names should contain a maximum of 4 small letters (e.g. xadm ).

Module names can be arrived at keeping in mind the following points:

The module name could clearly identify the functional area which the module addresses.  E.g.: xadmio.c, mdmSave.c, mdmClone.c, mdmu.c.

The module name could identify a particular user interface/messaging object which the module addresses.  E.g.: mdmIcon.c, udmmBar.c, udmmFont.c, mdmFldId.c.

The module name could just describe if it deals with user interface or backend.  E.g.: udmmBknd.c

The main module (containing function main() or entry point to the application) should be <application_name>.c.  E.g... xadm.c, mdm.c.

The naming conventions for each of these kinds of applications/libraries are listed in the following tables.
Table 3 - Source file naming convention for applications/libraries
Name
Description
xadm.c
Main module
xadmio.c
Module containing functions performing I/O using API.
xadmp.c
Module containing page routines supported by the application.
xadmu.c
Module containing utility routines (typically to assist I/O functions defined in xadmio.c - processing of data after I/O)
udmmBknd.c
Module containing code for interfacing with the application infrastructure.

Note: The link between function names and the source file names should be maintained, so that given a function name it is easy to determine which source file contains its definition.

E.g.:  xadm which is an API-based application could possibly have a file named xadmio.c ( all the input/output routines) . So all the function names could start as xadmio_readline( ).

3.1.2     3.1.2           Header files

The initial 8 characters for header files should be made up as follows:
<application name><extension>

Application names should contain a maximum of 4 small letters (e.g. xadm )

There should always be a header file called <application_name>.h.  All the other header files can be included via this header file.

Extensions will be chosen to clearly indicate what the header file contains.

The header file naming conventions for pure API-based applications/libraries are given in the table below:
Table 2: Header file naming convention for API applications/libraries (short filenames)
Name
Description
xadm_d
Definition file containing structure definitions and typedefs for the structures
xadm_c
Constants and macros
xadm_f
Function Prototypes
xadm_p
Portability File
An optional ‘_p’ can be appended to ‘_d’, ‘_c’ and ‘_f’ extensions to indicate ‘portability’ related header files.

3.2     3.2 Functions

·         Function name can begin with module name followed by a description (e.g. xadm_save_all,  mdm_init_jazz_engine). The general logic to be applied while naming functions is
<application + module_name>_<operation>_<object>

·         Only functions which are not called explicitly anywhere can begin without a module name. Typically notify, issue functions, event handlers etc. which are assigned to function pointers or are called intrinsically come under this category. (e.g. set_domain_background_color_issue).


Functions called from outside of a file must be defined by prototypes in an include         file (for that file).  This implies that prototypes should never occur in C source files (.c files); instead, the .c file should #include the appropriate include file.  For example, if the file cashflow.c defines the functions GtoFree CFL and Gto NewCFL, the include file cashflow.h should contain:

  TcashFlowList     *GtoNewCFL
                                                              (TDate  *dates,            /* (I) Dates */
                                                                            double *amounts,      /* (I) Amounts */
                                                                           int      numItems);   /* (I) Length */
      void GtoFreeCFL (TCashFlowList *); /* Destructor */


Any time there is a need for more than a couple lines of code in more than one place, the code must be placed in one function or macro which is then called from multiple places.


In general, functions must not be longer than a page or two.  Nesting of  for, while, do, and if statements should not be more than four levels deep.


Within a file, higher level functions (those which call other functions) must come first.

3.3     3.3 Variables

·         All variables are to be named in Hungarian Notation using alpha-numeric characters only. The data type is prefixed to the variable name based on the following table :

Table 1 : C variable naming convention

Prefix
Data type
Example
1.       i
1.       int (signed and unsigned)
1.       iIndex
2.       c
2.       char (signed and unsigned)
2.       cOperator
3.       f
3.       function
3.       fButtonNotify
4.       d
4.       double
4.       dAskPrice
5.       s
5.       structure or typedef structure
5.       sTradeGroup,  sEnv
6.       p
6.       pointer
6.       pHndl
7.       pts
7.       pointer to ‘type defined’ structure
7.       ptsTradeGroup
8.       pc
8.       pointer to character array
8.       pcCharacterArray
9.       pd
9.       pointer to double
9.       pdBidPrice
10.    pi
10.    pointer to integer
10.    piIndexToArray
11.    pv
11.    pointer to void
11.    pvVoid
12.    a
12.    function arguments whose value will be returned to its caller.
12.    aHndl
13.    ac
13.    array of char or address of char
13.    acOperator
14.    ai
14.    array of integers or address of integer
14.    aiErrorCode
15.    ad
15.    array of double or address of double
15.    adAskPrice
16.    ap
16.    array of pointers or address of pointer
16.    apNameList

For register variables, add ‘Reg’ after the prefix (eg. iRegLoopCount)

4.     4.    Data Structures

4.1     4.1 Define Structures as Typedefs

All structures must be defined as a typedef.  For example:

      typedef struct
  {
        int         fNumItems;
        TDate *fArray;
  }     TDateList;

4.2     4.2 Structure Tags

All structures must have a tag which names the structure preceded by a single underscore.  In other words, the previous example should really look like this:

      typedef struct _TDateList     /* Tag here */
  {
        int         fNumItems;
        TDate *fArray;
  }  TDateList;

5.     5.    Programming conventions

5.1     5.1 Source files

The source file structure should generally adhere to the following layout :

Comment block for module description (see section : 6.1 )

All source files should be surrounded by

#ifndef  <source_file_name>_C_INCLUDED    /* eg. MDM_C_INCLUDED */
#define <source_file_name>_C_INCLUDED
:
:
#endif                                                                                           /* At the end of file */

#include header files

Macros (#defines) block to define all macros specific to this source module

Static Globals block. The order is C data types, application data types followed by user defined data types

Static function prototypes block

Functions definitions.

5.2     5.2 Header Files

All header files should be surrounded by

#ifndef  <header_file_name>_H_INCLUDED   /* eg. OS_H_INCLUDED */
#define <header_file_name>_H_INCLUDED
:
:     (contents of header file)
#endif

5.3     5.3 Variables

The following conventions should be followed while naming and locating the C variables:

Variables should be declared individually, one per line.

Correct
int   iIndex;
int   iSeconds;
Incorrect
int   iIndex, iSeconds;

Variables should be named as defined in  section 3.3

The format for defining pointers is :
<type><space>*<one or more spaces><pointer variable>;
E.g.:
int *     pCode;
char *   pcBuf;

Static variables to be defined in the source files only

Global variables should be always be defined as
EXTERN  struct tsNCharcb      sOpenRoutineName;
where EXTERN is defined as
#ifdef      <application_name>_C_INCLUDED
#define     EXTERN
#elseif
#define     EXTERN      extern
#endif

Global variables should not be initialized during declaration

Global variables should be initialized separately in a initialization routine

Initialize only one variable per statement.

Correct
iIndex = 0;
iSeconds = 0;
Incorrect
iIndex = iSeconds = 0;

Separate the “tokens” in the intended manner
e.g. write y = x / *p; rather than y=x/*p;

(*p is the value pointed to by p, in the second case everything  beyond x is treated as comment and the intent is lost)

Do not assume automatic initialization of Global variables

Avoid using static variables inside functions unless it is absolutely necessary

Register variables should be used only for counters for large loops. Preferably let the compiler handle register optimization

Explicitly modify variables which occur more than once in one statement; not as part of the statement itself

Correct
iXXX = piYYY[iIndex] + piZZZ[iIndex];
iIndex++;
Incorrect
iXXX = piYYY[iIndex] + piZZZ[iIndex++];

5.4     5.4 Functions

The following conventions should be followed while writing functions

Prototypes of static functions should be included in the source files only

Arguments should be listed one per line in a function’s declaration and in its prototype



Example:

int read_emp_all
(
                                                char acEmpNo[],
                                                char  acEmpName[],
                                                float  iEmpSalary
)   

When a call to a function spans more than one line, each argument should be placed on its own line

Upon success, a function should return an int whose value is set to OK, otherwise it should return an int whose value is set to NOT_OK

The last argument to a function should be an int * for which dereferencing is valid only when the function returns NOT_OK

Return arguments should be enclosed in parenthesis

Functions should be written in pairs - one to do something an the other to undo it.

5.5     5.5 Braces and Indentation

Left braces should appear five spaces indented from the beginning of the previous line

A right brace should appear in the same column as its matching left brace

Other statements should appear on the same line as a brace except at function level where the left brace appears on the first column and the statements appear five spaces indented from the left brace

When multiple arguments of a function call are written one per line, all the arguments should appear on the same column as the first argument. For pointer data types, the * is placed immediately after the data type with a single space between them. The variable names should be aligned to the same column.

int xadm_add_to_socket_list(    tsDialogInfo *        ptsDialogInfo,
  tsNCharcb *           ptsSocketName,
  tsNCharcb *           ptsSocketAddr,
  int *                 aiCode)

5.6     5.6 Other Issues

The following issues should be observed carefully to write portable and understandable code

Do not assume the sizes of various data types. Always use the sizeof operator. An integer on a 16-bit operating system may be 2 bytes while on a 32-bit operating system, it may be 4 bytes.

Use parentheses judiciously to make the code more readable
for e.g.

*sStatus.piErrorCode is less readable than *(sStatus.piErrorCode)

If a statement appears over-parenthesized, break it up into multiple statements

goto statements should not be used

Do not use “break” to come out of loops; use flags instead

Always handle default in switch statements. Every case statement block should have a break statement.

Correct
switch(iItemType) {
      case TYPE_A :
            ...
            break;
      case TYPE_B :
            ...
            break;
      default :
            ...
            break;
      }
Incorrect
switch (iItemType) {
      case TYPE_A :
            ...
            break;
      case TYPE_B :
            ...
      }

Avoid magic numbers. Always use #define or const to represent such numbers

Correct
#define     MAX_CLASS_SIZE    36
...
if (iClassSize < MAX_CLASS_SIZE)
      ...
Incorrect
if (iClassSize < 36)
      ...

For frequently used strings, use a const char *. This is preferable to using #define macro to declare constant strings.

Correct
const char  *pPrompt = “Press any key to continue”;
...
printf(pPrompt);
...
printf(pPrompt);
...
printf(pPrompt);

Incorrect
...
printf(“Press any key to continue”);
...
printf(“Press any key to continue”);
...
printf(“Press any key to continue”);

6.     6.    Documentation

Documentation is to be provided for the following purposes :

6.1     6.1 Source header and modification history

All source and header files will contain a section providing information about the source or the header file. The format is given below

/* File        : <filename>
 *
 * Description : <description>
 *
 * Author      : <author> (Infosys Tech. Ltd., Bangalore)
 *
 * Started On  : 6 June 1996
 *
 * Modification History :
 *
 *  Date       Name          Change/Description
 * ------------------------------------------------------------------
 * DDMMMYYYY   xxxxxxxxxxx   yyyyyyy yyyyy yyyyyyyyy yyyyy yyy yy yyy
 *
 */

The modification history should record any significant changes to the program logic.

6.2     6.2 Procedure headers

All function are preceded by a comment block which will be of the format given below

/*********************** 80 characters wide ******************************
 * Function     : <Function Name>                                        *
 * Description  : <Overview of the function>                             *
 *                                                                       *
 * Input Parameters:                                                    *
 *                                                                       *
 *                                                                       *
 * Returns      :                                                        *
 *                                                                       *
 * Globals      :                                                        *
 *                                                                       *
 * Static funcs : aaaaa()                                                *
 * Extern funcs : bbbbb()                                                *
 *                                                                       *
 *************************************************************************/

6.3     6.3 In-line and block comments

In-line comments are discouraged.  Provide in-line comments only if they are a must

Other comments should begin with the same indentation as the succeeding source code and end on the 80th column

Blank lines occur before and after the comment blocks.

Avoid commenting individual statements. Instead comment a group of statements explaining the logic

Avoid trivial comments like /* increment counter */


Comments

Popular posts from this blog

C Questions

C Questions
C Questions

Note : All the programs are tested under Turbo C/C++ compilers.
It is assumed that,
Programs run under DOS environment, The underlying machine is an x86 system, Program is compiled using Turbo C/C++ compiler.
The program output may depend on the information based on this assumptions (for example sizeof(int) == 2 may be assumed).
Predict the output or error(s) for the following:

void main()
{
int const * p=5; printf("%d",++(*p));
}
Answer:
Compiler error: Cannot modify a constant value.
Explanation:
p is a pointer to a "constant integer". But we tried to change the value of the "constant integer".
main()
{
char s[ ]="man"; int i;
for(i=0;s[ i ];i++)
printf("\n%c%c%c%c",s[ i ],*(s+i),*(i+s),i[s]);
}
Answer: mmmm
aaaa nnnn
Explanation

Zoho Interview | Set 1 (Advanced Programming Round)

Third Round: (Advanced Programming Round) Here they asked us to create a “Railway reservation system” and gave us 4 modules. The modules were:
    1. Booking
    2. Availability checking
    3. Cancellation
    4. Prepare chart
We were asked to create the modules for representing each data first and to continue with the implementation phase.

 My Solution :

#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<string.h>#include<iostream.h>#include<time.h>#include<iomanip.h>#include<fstream.h>char f[10]="f";char s[10]="s";int addr,ad,flag,f1,d,m,i,amt;float tamt; class login {public:char id[100];char pass[100];char*password;void getid(){ cout<<"Enter your id:";gets(id); password=getpass("Enter the password:");strcpy(pass,password);}void displayid(){ cout<<"Id:";puts(id); cout<<"Password:";puts(pass);}}; class detail {public:in…

Hackerrank > SQL > Basic Select

Select
01-Select All
Given a City table, whose fields are described as +-------------+----------+ | Field       | Type     | +-------------+----------+ | ID          | int(11)  | | Name        | char(35) | | CountryCode | char(3)  | | District    | char(20) | | Population  | int(11)  | +-------------+----------+
write a query that will fetch all columns for every row in the table.

My Solution
SELECT*FROM city;
---------------------------------------------------------------------------------
02-Select by ID
Given a City table, whose fields are described as