About coding style - page 3

 

I prefer to separate the functions into separate actions, so that the code has a clear structure... it's easier to optimise...

 
Mathemat >> :

Basically, it's normal code that performs the same calculations as the nested if construction. But somewhere I've heard that return in the function should be one. Probably, it's done in order not to get mixed up in them. I do not strictly follow this rule.

In other respects my approach is very close to yours, C-4, except for a couple of details.


Yes, there is such an opinion. But return operator is not the same thing as GOTO. In practice I have never encountered any unexpected return throws. On the contrary, the program becomes more readable and textured when such operators and conditions are used (all the checks go one by one from the top downwards forming a kind of a column). Besides, unlike if() operator return guarantees an exit from the function, and this is exactly what is needed in most cases, because there is no point in evaluating data further if some condition is not fulfilled.

 

I really liked the last rule: "Never use the 'copy and paste' operation". But, alas, I don't follow it. How is it possible to use the IDE editor and not to use "Copy&Paste" which saves a lot of time?

As it turns out, no, it does not: I notice that it is because of this that I often find logical errors, which are hard to catch.

P.S. The forum engine doesn't allow me to format this fragment from my first post

// open
// .pairsToOpen
// .combineAndVerify( )
// Собирает из двух валют символ и выполняет все проверки, нужные для его открытия.
// Возвращает валидность пары для открытия.
// Последний аргумент - [...]
bool
combineAndVerify( string quoted, string base, double& fp1 )

Exactly the way it's made with me: the first three lines look different, more structured. OK, by hook or by crook:


How I comment functions

 

Here are a few more rules that have come to mind recently and that I have already implemented in my own place:


1. Global Variables (GV) are not declared all at the beginning of the code, but as needed, before the corresponding functions that use them.

2. Before each function, we also describe which GPs it uses (input) and which ones it modifies (output) when it is actually called. And after the function, you can also explain which GPs will no longer be used.

3. All these comments, along with empty separator lines between functions and limitation "function length not more than 20 lines" increase the size of the code file 1.5-2 times. It doesn't make it harder to compile, and we don't have paper to spare on it.

4. What are GPs useful for? Suppose we calculate some variable variable of a complex type in function foo( ..., <type>& variable ), passing it by reference. Then, if we use this variable repeatedly in various code fragments, we will have to call the foo( ) function each time. It seems to be OK - apart from spending time each time for evaluation of this variable, we also add a couple of lines (for variable declaration and function call) into each function using variable. Why? If this is so called code reuse, it is somehow suboptimal: apart from making foo( ) function too frequent in use, we also break structure of function calls, making user foo( ) function "out of categories" and its calls non-hierarchical. It's easier to declare variable as an "out of category" variable, i.e. global.

Personally, I'd prefer strict hierarchical functions to such questionable code reuse. I've already said about hierarchy: each function of the n-th order is called only by a function of the (n-1)-th order and only "its own" function. See my example explaining the function hierarchy in the picture with green background above.

5. But of course, the code is not always optimal in the sense of hierarchy, and sometimes you have to call "alien" functions. In this case you can write its place in the function hierarchy in brackets /* */ before the name of the "alien" function.


Maybe all this is silly and excessive, but I know very well that I am writing code that I will probably have to edit more than once. Here I think it's better to reassure myself in commenting and structure.

 
Vinin >> :
On the size of the function. I try to make the function fit to one screen. So that you can see the whole thing.

I try to write code so that the source code could be corrected in blocks, and it is convenient to add and change

comments should be no less than 30% of the code size

( learned to do this in the 80x, looking at the source code of UNIX operating systems, RT11)

half a year later the code is forgotten - if you need to correct it, the comments give you a quick understanding of the subject !

(I had a real experience at a production site when I was reading my own code after 5 years)

thanks to comments I remembered everything in one day and made changes by the evening)

I try to align code for readability not to skimp on spaces and indents

compare the two examples ! which code reads better ?


1)

extern string gslM001rus="Все что касается индикации" ;
// 
extern bool gpInfoParameter =false ; // выводить параметры
extern bool gpInfoLevel =true ; // выводить параметры
extern bool _gDeleteObjectGrafic =0 ; // 1-Удалять объекты на графике при завершении 0-не удалять
extern double FlatSBuy =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell =0.0010 ; // =0.00050; // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int DayHistory =50 ; // Сколько дней в истории показывать
// флет азии 
extern int iTimeEndFlatAsiaHour = 5 ; // Конец утреннего флета
extern int iTimeEndFlatAsiaMin = 15 ; // Конец утреннего флета
// Время длины флета измеряется минутами от окончания и назад
// 360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
extern int iTimeEndFlatAsiaSizeMin = 360 ; // + количество минут  флета// 
extern string sTimeBreakFlatAsia ="20:00:00" ; // Время до которого разумно ждать пробой и выставление ордеров
extern int pУровниHighLowDAY =1 ; // выводить уровни HIGH LOW
extern color ЦветПятницыHIGH =DeepSkyBlue ;
extern color ЦветПятницыLOW =DeepSkyBlue ;
extern color ЦветHIGHDAY =DarkViolet ;
extern color ЦветLOWDAY =DarkViolet ;
extern color lColorFAH =OrangeRed ;
extern color lColorFAL =SandyBrown ;
extern color lColorSignalSELL =Red ;
extern color lColorSignalBUY =Red ;

 


2)


extern string gslM001rus="Все что касается индикации"      ;
//                                                                  
extern bool   gpInfoParameter         =false               ; // выводить параметры
extern bool   gpInfoLevel             =true                ; // выводить параметры
extern bool   _gDeleteObjectGrafic    =0                   ; // 1-Удалять объекты на графике при завершении 0-не удалять
//                                                            
extern double FlatSBuy                =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern double FlatSSell               =0.0010              ; // =0.00050;  // пипов на пробой ТОЛЬКО ДЛЯ ИНДИКАТОРА!!!
extern int    DayHistory              =50                  ; // Сколько дней в истории показывать

//                                                         
// флет азии                                               
//                                                         
extern int    iTimeEndFlatAsiaHour    = 5                  ; // Конец утреннего флета
extern int    iTimeEndFlatAsiaMin     = 15                 ; // Конец утреннего флета
// 
// Время длины флета измеряется минутами от окончания  и назад
//   360 минут эт о6 часов назад от 5:15 получаем 23:15 вчерашнего дня
//
extern int    iTimeEndFlatAsiaSizeMin = 360                ; // + количество минут  флета
//                                                            
//                                                              
//                                                            
extern string sTimeBreakFlatAsia      ="20:00:00"          ; // Время до которого разумно ждать пробой и выставление ордеров
//                                                         
extern int    pУровниHighLowDAY       =1                   ; // выводить уровни HIGH LOW
//
extern color  ЦветПятницыHIGH         =DeepSkyBlue         ;
extern color  ЦветПятницыLOW          =DeepSkyBlue         ;
extern color  ЦветHIGHDAY             =DarkViolet          ;
extern color  ЦветLOWDAY              =DarkViolet          ;
extern color  lColorFAH               =OrangeRed           ;
extern color  lColorFAL               =SandyBrown          ;
extern color  lColorSignalSELL        =Red                 ;
extern color  lColorSignalBUY         =Red                 ;
//
//
 
                                                    
 
Mathemat >> :

if(param1!=1)return;

if(param2!=2)return;

...

if(param5!=5)return;

Print("Наконец-то дошли!");

Basically, it's normal code that performs the same calculations as the nested if construction. But somewhere I've heard that return in the function should be one. Probably, it's done to avoid getting mixed up in them. I do not strictly follow this rule.

As for the rest, my approach is very close to yours, except for a couple of details.

I prefer the same way of going out alone!

easier to control


If you want to return a value, then


instead of

if ( a > c )

return ( 3 );

if ( l < b )

return (5);

...

...

if ( h != b )

return (100);

---

prefer


if ( a > c )

codret = 3;

if ( l < b )

codret = 5;

...

...

if ( h != b )

codret = 100;


// especially if some additional operations common for all outputs are performed before return

... for example here we do something else

retrun( codret);

}


 

a little bit of commentary...

To divide texts into blocks I use a line of characters with code U0151. For those who don't know, it's typed like this:

  1. hold down Alt
  2. on the numeric keyboard press in sequence the digits of the symbol code 0 then 1 then 5 then 1
  3. release Alt

for "correct" fonts we get a minus sign but without "spaces" at the ends. then copy it as many times as needed a solid line which serves as a good visual border...

// обычная линия
// -----------------------------------------------------------------------------------

// сплошная линия
// —————————————————————————————————

// —————————————————————————————————
// Вот такие часто делаю ЗАГОЛОВКИ
// —————————————————————————————————

 

also a clever chunking line for the comment text block - it looks perfectly symmetrical, but there is a first-opening and a second-closing line:


/*///—————————————————————————————————————————
это

multi-line comment block
...................

/*///-----------------------------------------

 

Yura, your example with one return, of course, is logical. But pay attention that in this case all ifs are always run, unlike the case with many return, when the exit from the function is obtained immediately after reaching the string with the condition.

ForexTools, thank you, I've taken on board your design ideas.

Reason: