Showing posts with label IDE. Show all posts
Showing posts with label IDE. Show all posts

Wednesday, 5 April 2017

Development : Anti-Hungarian Notation

Whilst cutting code I employ a coding style, which I enforce, whereby I output the scope of the variable being used with a prefix.

"l_" for Local
"m_" for Member
"c_" for constant
"e_" for enum

And so forth, for static, parameter and a couple of others.  I also allow compounds of these, so a static constant would be:

"sc_"

This is useful in many languages, and imperative in those which are not type strict, such as Python.

Some confuse this with "Hungarian Notation", it's not.  Hungarian notation is the practice of prefixing a type notification to the variable name, for example "an integer called count" might be "iCount".

I have several problems with anyone using Hungarian Notation, and argue against it thus. With modern code completion and IDE lookup tools this is really not needed, with useful and meaningful naming of your variables the type is not needed and finally there are multiple types with the same possible meaning... i.e. "bool", "BYTE" and "std::bitset" are they all 'b'?  What about signing notation, so you compound "unsigned long" as "ul" to the name?

It all gets rather messy, a good name is enough.

However, the scope of the variable might change, the scope might not be enforced, and in none strict languages you might have a variable go out of scope and then automatically re-create the value with a blank value, if you don't follow your scopes.

Therefore I can justify my usage and enforcement of this coding standard.

What I can't stand however is when someone listens to my explaining this, they read my coding standards document, they even go as far as having me reject their code during peer review for these reasons, and then they dismiss my comment with the "it's just Hungarian Notation"... Scope is not type, and type does not define scope, don't be fooled!

Tuesday, 26 April 2016

GNU C/C++14 Installation & Codeblocks 16.01 from Source (Command Line)

In yesterdays post I explained a C++14 user was having instant issues with the vanilla install of gcc/g++ on Ubuntu 14.04 LTS.

Getting a C++14 Compiler
So, here today are my command-line steps to update the GNU Toolchain v5.x.

sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get install gcc-5 g++-5

If you already have compiler alternatives you may need these lines.

sudo update-alternatives
sudo update-alternatives --remove-all gcc
sudo update-alternatives --remove-all g++

But, everyone will need to swap the default gcc and g++ command-lines to the new paths to make them the defaults.

sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 20
sudo update-alternatives --config gcc
sudo update-alternatives --config g++

These last two --config commands are only needed if you have multiple alterantives, so don't worry if it tells you it's failed as you only have the one.

Now, if you perform g++ --version, you should see it's a version 5.x series compiler.

Codeblocks 16.01
Older versions of Codeblocks may start to error on the code completion with some of the C++14 specific commands.  So, we need install some prerequisites, and then build the latest 16.01 version from source.

sudo apt-get instal gtk+-2.0 automake libtool libwxgtk2.8-dev libwxbase2.8-dev

wget http://sourceforge.net/projects/codeblocks/files/Sources/16.01/codeblocks_16.01.tar.gz

tar -xvf codeblocks_16.01.tar.gz

cd code*

The next step is interesting, we need to iteratively check:

./bootstrap

Running this will show you anything wrong with your machine environment, any missing dependences etc... However, once bootstrap runs cleanly, you can continue below.

./configure
make
sudo make install

The make step takes quite a time, the more cores & RAM you have the better, on an 4 core (8 thread) machine with 8 GB of ram, I've found it takes about 10 minutes.  On a single core machine as the poor VM I had was assigned, it took a lllooooottttt longer.

Once complete we needed to use the text editor of our choice, in sudo mode....

sudo nano /etc/ld.so.conf

And to this we need to add the line:

include /usr/local/lib

Save the file, exit the editor and run:

sudo ldconfig

Once this was complete, we can run up Codeblocks, and see it's version 16.01.



And we can further see the nice new C++14 options in the build options:



Even the code highlighting recognises the make_shared operation:



Voila, if this helped, do check out my other posts, and code, leave a tip with my new tip jar!  And I'll be making a video of this one soon, as it's so useful.

Friday, 1 April 2016

Coding Standards: Functional Programming (Code Maintainability)

Functional Programming

When I were a lad, and was being taught to program, I read a bunch of Basic code and wrote great long lists of instructions; that's pretty much how many people in the 90's described programmers, coders or hackers "someone who spends lots of times typing great long lists of instructions into their computer" - Robert X Cringley.

However, long lists only get you so far, so my next step into the world of programming was to learn Pascal, and I first read a simple book as part of my A-Level, by P. M. Heathcote, which introduced very basic programs in Pascal, something like...

program HelloWorld (input, output)
begin
    println ('hello world');
end;

So, I suddenly had this idea of putting the long lists of instructions into sort of functions:

program HelloWorld2 (input, output)

   procedure foo()
   begin
       println ('foo');
   end;
   
   procedure bar()
   begin
       println ('bar');
   end;
   
begin
   print ('hello ');
   foo();
   print (' and hello ');
   bar();
end;

(Note: before you call me out and say you can "GOSUB" or "CALL" other functions in BASIC, not in the dialect I first learned, all you could do was SUB to a line number, following the instructions until you used RET to go back to where you were... So they were technical functions, or procedures, but they were really just more lines of code within the huge list of lines of code, no indentified in anyway, except by comments, as being functions).

Interestingly at this time, I was taught there were two kinds of functions you could call, ones which returned a value, known as "functions" in Pascal, and ones which didn't return anything known as "Procedures".  These latter you'll be very aware of from other langugages like C, where the return type is part of the function declaration, so "void foo();" obviously doesn't return anthing, whilst "int bar();" returns an integer.

That "Procedure/Function" definition stuck with me a long while, I was a kid, I was taught something and got a certificate to say to the world "He knows what he's talking about", so it was with some trepidation, years later, that I had to admit it was rubbish and everything was a function.

And this revelation came with my being taught about "Functional Programming", this was important for large projects written in languages like C, because you really wanted to start to learn how to keep functions doing one task.  So when you designed, named, write and test a piece of code, you can break it down, and know each piece, or each function, is doing just one job.

"void Max(const int& p_Left, const int& p_Right, int& p_Result)"

Here I've just defined a function prototype, even without my explaining, I'm pretty sure you could guess what it does... Yes, it takes the left and right integers given and decides which is the bigger, placing that value in the result.

We can design code, define the prototype, and hand the nitty gritty of the actual code body of to someone else, to write the body of it, or just to test our implementation works.  And though this is a trivial example, think about a single function to say format a disk, it might contain calls to dozens, or hundreds, of other functions, but it itself does one task, and each sub task is itself kept in a single function so you break the whole job down.  Within your large projects therefore you maintain a level of ease in how to debug, maintain and update the code, if your "foo" function doesn't work, just fix that one function and re-test, there shouldn't be multiple-foo's and there shouldn't be more than one task performed within the code inside "foo".

This was the first major meeting, and teaching, I had on "Functional Programming", and it was something I took to heart.  My code took on very much a "one function" style, where each function had a single purpose.

Twenty years on, and even in an Object Orientated world (of C++, C# and Java) I utilise the functional idea.

The main thing applying the single function ideal to my code has lead to is a vast improvement in maintainability, this has been important for my job and on going sanity with large projects.

However, there are other caviates, for there are other parts to functional thinking which have to be taken into account.  For example, are you going to allow functions in your code to have just one, or multiple exit points from a function?  For example:

const int bar (const int& p_i)
{
   return p_i * 2;
}

const int foo ()
{
    if ( x > 0)
    {
        return bar(x);
    }
    else
    {
    return bar(-x);
    }
}

This is perfectly reasonable code, foo does one job, deciding upon the value of x which value to pass, however, this is a trivial example, what if there are tens, hundreds or even thousands of different paths you could take as the result of foo?... A case statement with every character possible already throws hundreds of options our way, so it's not out of the ordinary.

You could be tracing through this code and ANY of those many exit points could fail, causing a crash, which you then have to dig through after the stack has all unwound.

Using many exit points is fine, if you can justify it, please don't get the impression I'm hating on the concept, if you have a low memory situation for example, I can see you won't have space spare for my suggested solution; and this is part of the many trade-offs you will learn about in a career of programming, when to, and when not to employ a technique.

But in the above example, I would change foo as follows:

const int foo ()
{
    int l_result = 0;
    if ( x > 0)
    {
l_result = bar(x);
    }
    else
    {
    l_result = bar(-x);
    }
    return l_result;
}

So, you see I have a local value copy, this is using more memory, and wants to allocate that memory... and there are other options than allocating that as a local variable, but for maximum maintainability keeping that value within the actual function is a key feature of this example.

And so how does this assist in maintainability?  Well, we can now debug the function a lot more easily, we can see the value of "l_result" at any moment in a watch within the debugger, we can wrap individual - failing - calls to "bar" into try-catch statements and debug the returned value for the whole function at the return at the bottom.

I've seen some horrors in the poor use of both returning from within a function, where return points are hidden three, four or more nestings deep, and it's made for nothing but frustration, try to avoid multiple function exit points.

What else does functional programming offer us?... Well, it also offers us an easy way to make code self-documenting, if we have a function like the "max" function earlier, it explained itself in just it's definition, take advantage of that fact.

But what about functions inside objects?  I hear you cry, well lets take a pure C++ example, in C++ (or at least most C++ compilers) we're allowed to just define a function prototype and go to town, but that's really; technically; C not C++.  To make things C++ we really should have the functions all inside a class definition... I stick to this idea, even if we just need a pseudo class of static functions:

class Helpers
{
    public:
    
          static void Max(const int& p_Left, const int& p_Right, int& p_Result);
          
          static const int Sum(const int& p_Left, const int& p_Right);
          
 };

 One can see what the functions mean, and the function have meaningful names, the class itself can have, a useful name, and indeed the class can then be in a namespace which itself has an even more useful name.  So we build up not complexity, as some assume, but ease of division of functionality, breaking numbers from user interfaces from strings from file management, break it down, divide and conquer, that was the original purpose of functions in computing, and so that original function is now emphasised in the languages and methods we employ today.

 C++, C#, java, Python, all can benefit from using the function idiom... Your projects certainly can.

Thursday, 15 May 2014

Setting up Code::Blocks & Boost on Windows

Updated for 2016: https://youtu.be/Mioo8Hnp6M8

Below is an older post, please see the new YouTube Video, like subscribe & if you benefited the tip jar is just there on the right!

Xel - 5th JUne 2016.




Building boost with Mingw32, installed via CodeBlocks....

First things first, download the installer for CodeBlocks for Windows, I selected the mingw32 compiler, at the time of writing this is:

codeblocks-13.12mingw-setup.exe

From the downloads page.

A quick example program can then be thrown together from the IDE, I'm interested in pure C++ using C++11, so I set the compiler to use -std=c++11 switches, as well as fix up the warning settings.


Once we're happy with the test project in the IDE we can go to the same file in a command prompt:


What we've just seen is, adding the compiler installed by codeblocks to the environment path:

PATH=%PATH%;C:\program files\CodeBlocks\MinGW\bin

We then edited the file with note pad:

#include <iostream>

using namespace std;

int main ()
{
cout << "Hello World" << endl;
}

Then from the command line we built the program:

mingw32-g++ -std=c++11 -Wall -o main.exe main.cpp

This gave us our application, and we could run "main.exe".


Now we've got all that working, my project uses the C++ boost libraries, so we need to build them with the mingw32 tools we've installed.


So, again we need a command prompt and the same PATH setting we have above:

PATH=%PATH%;C:\program files\CodeBlocks\MinGW\bin

Then from the boost folder we've extracted the boost source to, we need to build the boost build engine:

bootstrap.bat mingw

Once this is complete, we can build the libraries themselves:

b2 toolset=gcc

We now have the libs for linking in the boost sub folder /stage/lib

And we can find the headers in /boost...

We won't cover accessing them through the command line, instead BACK TO CODE BLOCKS!


So, we fire up code blocks, create a new project, its empty, we create our main.cpp and add "Hello World" in there.

We set the compiler to "-Wall" and "-Weff" and "=std=c++11", and check the compile & link worked.

Then we have to add the boost libraries, these are the system library, now we are in debug mode for this project, so we link against the libboost-system library with an added 'd' for debug.  If we switch to release with the drop down at the top, we need to add the link to the library which is not debug!

We also add the libboost-filesystem library, again in debug.

Finally, in the search directories we tell everything were to find boost itself, this allows our #includes to find boost headers.

I keep the paths relative, so I know whether I move my code and boost to "C:\Code" or "C:\Users\Jon\Desktop" the paths will be okay.

Then in the code, we'll include a check for a file on the file system, so include the boost filesystem header.  Then we add a path to "C:\hello.txt", and an exists check on that file...

CODE::BLOCK BUG/QUIRK!
And we build, now this is the first quirk you'll find, if you just build now the compiler will go off and start to rebuild boost... This is just stupid, so as the text is streaming past, ABORT the build, and then right click on the source file and build from there, you should see nothing needs doing.  Then rebuild again and the project is done almost instantly, this is a quirk of Code::Blocks, as it caches boost into the list of items built.... But we already built boost... 

Follow the video, it'll make sense.


#include <iostream>
#include <string>

#include <boost/filesystem.hpp>

using namespace std;

int main ()
{
    cout << "HEllo World" << endl;


    cout << "Testing if \"C:\\Hello.txt\" exists" << endl;

    boost::filesystem::path l_path("c:\\Hello.txt");
    if ( boost::filesystem::exists(l_path) )
    {

        cout << "File does exist!" << endl;
    }
    else
    {

        cout << "File missing" << endl;
    }

}

From the command line, we would have to add "-l libboost_system-mgw47-mt-d-1_55.a" and "-l libboost_filesystem-mgw47-mt-d-1-55.a", to link against boost.

The boost libraries we have are of course the dynamic libraries, if you wish to contain the libraries into the application you're distributing rather than having to hand out the libraries you've also built, you need to build the application static and rebuild boost with the static flags, which is a topic for another day.

Sunday, 6 May 2012

Nano, Vim and Emacs

I'm using my linux systems a lot at the moment, last night I was porting a bunch of my uses of the boost threading library over to the c++11 standard threading model/objects.

I did this, for the most part, in a GUI on my windows machines, but for the two linux boxes running my CGI (written in C++) back-bone for file publishing, I had to use the command line.

And I got thinking about better editors for the command line.

Now, I know about nano (use it all the time), I like its ease of use over Vim, it supports text colour highlighting and it is a very simple interface (anyone out there struggling with it?... The ^ (or hat) symbol means "Press CTRL".... So to output the file CTRL+O... which they show as ^O).

Anyway, I then got looking at the other command line editors available, Vi, of course is on most all *nux based systems, so I support at some point I better get around to looking at it.  Indeed in this month's (May 2012) Linux Format contains a tutorial by Jonathan Roberts, on how to use Vim... However, I find following his tutorial, or even the previous brief introduction, hard... Not because the information is not presented.  But that the presentation itself is not simple enough... Vi is a very alien working environment for the beginner, and many tutorials assume too much of the user to introduce them to it easily.

Of course, one then also hears that once one masters Vim they get into emacs... personally, I've never looked at emacs... I know, I know... How can I call myself a Software Engineer and not know Emacs?.... But the truth is, I was using systems, coding on them, long before emacs, long before IDE's in general.

But, going back in history, I remember learning to program, not just on the BASIC interpreters on Commodore machines, but also in Pascal on the ST, with its horrid editor - and then swapping to the nicer "EvereST" editor.  But then later on the PC, my first IDE was Borland Turbo Pascal... And I loved it.

I also see "Free Pascal" on Linux faithfully reproduces the IDE of that era...

I'd love to see that editor support C++ Syntax highlighting and maybe code completion...

But, I doubt it ever will... So in the mean time, I'm going to try and learn to use Vi, and feedback here how I get on, if at all...