Showing posts with label functions. Show all posts
Showing posts with label functions. Show all posts

Monday, 15 October 2018

C++: To Reference or Not

Constant Something Reference or Something constant reference... I ask myself this in a similar manner as Prince Hamlet at the start of the nunnery scene... For as a C++ programmer and English speaker I've always found myself most comfortable using the phraseology thus:

const int X (0);

And to pass this to a function:

void foo (const int& p_X);

I find this most useful, we're passing a constant integer reference to the function... However, I was recently challenged that this meant something else to a reader, her input was that it meant "constant integer" reference, that is we would ONLY be able to pass "const int" instances, not "int" instances.   The thinking being:

const int X(0);
void foo(const int& p_X);

foo(X);

Would compile, whilst:

int Y(42)
void bar (const int& p_Y);

bar (Y);

Would fail to compile or at least spit out a warning because "int" was not able to be passed into the function as "constant integer" and "integer" to this reader were different types.

They're not really of course, constant is a decorator (and one which we can remove with const_cast) the aim of using "const int reference" as the type is not all of our purpose in declaring the function like so, the purpose is to communicate what we do with the value going into the function.

It is 100% not about stopping Y being passable into the function as above.

No, we want to tell any user of our code that within the functions "foo" and "bar" we do not change the value, if they pass Y to us with 42, when the function is complete Y will stil contain 42.  If the value could potentially change we would not be able to use "const" that's the purpose of passing const in this case.

Passing by reference is just to save us the time, effort and delay in allocating memory and taking a copy of the parameter before moving into the body of the function, so:

void bar (const int p_Y)

Would be the same operation as above, we tell the user we don't change the value of the parameter, but we do because we take a copy of the value being passed in and operate upon it.

The communication we get with this is very useful.

But of course, if we're using threaded programming and we pass a reference to a value at time point A, then sometime later elsewhere edit the referenced value, we may run into unexpected behaviour, so there is an argument sometimes to take a copy at the point of instantiating the child function, in the most part however, passing by reference is considered the norm.

Monday, 31 October 2016

Software Engineering : "warning: defaulted and deleted functions only available with -std=c++11"

warning: defaulted and deleted functions only available with -std=c++11 or -std=gnu++11

When you're using std=c++14??!?!?!  What the heck is going on here?

I've noticed this strange bit of behaviour with g++ and warning when compiling with multiple cores... I've stripped this example back to the bare minimum, so lets just define what we're building and then we'll look at the strange warning which comes out, first of all, we need to compile two files, completely independent of one another:

Main.cpp

#include <iostream>

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

This is our first file, the other has to be a class:

Data.h

#ifndef DATA_HEADER
#define DATA_HEADER

#include <string>

namespace Xelous
{
class Data
{
private:
std::string m_Data;
public:
Data(const std::string& p_Data);
const std::string& GetData() const;
};
}

#endif

And the code for this class looks like this:

#include "Data.h"

namespace Xelous
{
Data::Data(const std::string& p_Data)
:
m_Data(p_Data)
{
}
const std::string& Data::GetData() const
{
return m_Data;
}
}

This code so far is all fine, however, in our data header we don't want the default constructor, so we're going to just delete the default constructor, like this:

#ifndef DATA_HEADER
#define DATA_HEADER

#include <string>

namespace Xelous
{
class Data
{
private:
std::string m_Data;
public:
Data() = delete;
Data(const std::string& p_Data);
const std::string& GetData() const;
};

}

#endif

Fairly simple stuff so far, and no problems, no errors... However, I always build with "pedantic", especially as I get closer to release and I'm looking at code, so lets see my build file for the above project:

CC=g++
STD=c++14
WARNINGS=-Wall -Wfatal-errors
PEDANTIC=-pedantic
OUTPUT=example

MAIN=main
DATA=data

CompileMain: ${MAIN}.cpp
${CC} -std=${STD} ${WARNINGS} ${PEDANTIC} -c ${MAIN}.cpp -time
CompileData: ${DATA}.cpp
${CC} -std=${STD} ${WARNINGS} ${PEDANTIC} -c ${DATA}.cpp -time
Lets just stop there, and look what we have in the build file so far, we have the compiler, the STL version to use, the warnings, we're using pedantic and I'm only compiling the two files, there's no linking going on.

I always prefer this so I can trap individual compile errors or problems, speeding up the over all development... Once I'm happy both classes or files are clear I can then combine them into their link, by adding:

Link: ${DATA}.o ${MAIN}.o
${CC} -o ${OUTPUT} ${DATA}.o ${MAIN}.o -time
This will link everything up...

There isn't a problem with this code, we can save the file now and call "make" on those three targets and it will work fine... Let us just complete the make file:

clean:
rm -f ${DATA}.o
rm -f ${MAIN}.o
rm -f ${OUTPUT}
clearscreen:
clear
all: clean clearscreen CompileData CompileMain Link

These last three targets are our clear, a simple clear screen and then the "all" target, 

So, we can now "make all" and see this output:


Building one after the other is fine, however, if I use "j2" that is to make it build data and main on different cores at the same time, then link the result of both you get the above error:


Both compiles are being sent to the compiler with c++14, when we're using serial single focus compilation there is no warning, yet with two the warnings pops out?

I've actually run out of time on this very busy Sunday to look into this any further at the moment, I'm therefore going to schedule this for tomorrow and let it loose on the world...