If the erroneous line is supposed to be an initialization of a variable calling this constructor, then that is not going to work: you can not initialize a member variable right inside the class declaration, unless it is static. Instead you have to do the initialization inside the constructor, like this:

Thanks, that was indeed the problem. No idea why it was checked - I almost always use tags.

GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

Inside a function, this declares a variable called i2c_ads1115 with type CLASS_I2CIO and calls the constructor with the two values DEVICE_I2C and ADDRESS_ADS:

CLASS_I2CIO i2c_ads1115(DEVICE_I2C,ADDRESS_ADS);

Inside a class definition it declares a member function called i2c_ads1115 that returns a CLASS_I2CIO type and takes two arguments, which is where the compiler is having problems. Instead of DEVICE_I2C being a type, you have a #defined string.

To get i2c_ads1115 as a member variable, declare it the same way as the i2c_ioctl member variable, then construct it with arguments in the initialization list of the C_VNA class.

Thanks, I'll give it a go.
One more question.
Why I have no issue with using same syntax making an instance of the class in main ()?
Stupid question - could I just change the #define to "include" type ?

The compiler expects a function signature, but the function arguments you specified are missing a type.

Try somthing like this

CLASS_I2CIO i2c_ads1115_test(constchar* DEVICE_I2C, int ADDRESS_ADS);

(not sure what type the second argument is supposed to be)

GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)

Suppose I have a function that takes an array pointer and an index declared as type unsigned int and the function will access the array at that index.

AFAIK "Index < 0" should never evaluate to be true regardless of what the caller passed because the unsigned type will control how the bits at the address of Index are interpreted and there will be no interpretation of a bit as an indication of sign.

So implicitly an unsigned int is not capable of an access violation Below / before an array's first element given the pointer arithmetic. All that being said it does not seem at all necessary to test it.

There are other reasons to use the test however.
#1 it may improve readability as someone who reads the code sees that a full boundary check is being done
#2 it may make the code symmetric with other code that tests upper and lower boundaries of any other type of variable
#3 if the function is later modified and the type is accidentally changed to int (for example the types are changed when porting to a different machine architecture) or the code is copy and pasted to a different context where Index is not unsigned, omitting the bounds check introduces the possibility of an access violation
#4 I think it's possible, perhaps likely, that an intelligent compiler will optimize it out completely, even if it didn't we're not talking about a grave loss of efficiency.

So although I feel stupid writing what seems to be redundant and unnecessary code and concern myself with conciseness, for a robust application it seems worthwhile.

I would keep it simple: an unsigned cannot be less than zero, full stop.

This simple fact seems to be no longer on the curriculum! Wrote a bit about it to the caller!
I feel that an awfull lot of skills are no longer taught, the same skills I had to learn myself, e.g. How does a computer actually work! Registers,Stackpointers, The Stack and the Heap, the function of the OS, Machine Code, what does an assembler do, what does a compiler do, etc. I will encourage anyone willing to study 'C' or 'CPP'. These people on this queery seem to be basically stuck on the underlying hardware concepts.

So implicitly an unsigned int is not capable of an access violation Below / before an array's first element given the pointer arithmetic. All that being said it does not seem at all necessary to test it.

What you are ignoring is the code is invalid and would fail any software audit .. you handed that junk to me and I would sack you.

What you are ignoring if you turn the compiler warning levels to max then your code won't compile .. it will give you a fatal error. At half-arse programmer wannabe settings it probably just gives you a warning about passing a signed integer into an unsigned integer interface.

However in the real commercial world you run the compiler settings max and your code must not invoke any warning at all. Any good university when you submit your code for evaluation will have the compiler set to max you generate a warning you fail.

What you are ignoring is the code is invalid and would fail any software audit .. you handed that junk to me and I would sack you.

I'm writing proof/test of concept code to enhance my understanding of safe and secure programming practices. Of course it's invalid, that's the actual point. You should fire the guy who tests the security of code on your customers instead

leon de boer wrote:

What you are ignoring if you turn the compiler warning levels to max then your code won't compile .. it will give you a fatal error. At half-arse programmer wannabe settings it probably just gives you a warning about passing a signed integer into an unsigned integer interface.

Actually I wasn't aware of how to force my IDE to use the strictest evaluation, but I know now, thanks for the tip. You may be disappointed as it notices the issue now but only generates a warning:

However in the real commercial world you run the compiler settings max and your code must not invoke any warning at all. Any good university when you submit your code for evaluation will have the compiler set to max you generate a warning you fail.

Do they also run static code analysis? Are there any freeware tools I can use? Haven't looked into it yet.

I hope this is a question by a student. It would prove that there is at least One student still studying the 'C' language in this world. It also gives me a dark impression of your teacher. (unless if you missed lessons, or was not paying attention)

The situation is clearly not understood by you in terms of Bits and Bytes.

Signed or Unsigned is all a matter of interpretation, and, something called 2 compliment arithmetic. One Byte of 8 bits can only have 256 possible values, 0 to 255! (Hope you know and understand that much) The question is, how do we interpret this. We can take this as an unsigned range of 0 to 255, or, as a range of -127 to + 127. In the latter case the most significant bit will represent the sign. 1 for Negative, 0 for positive. The beauty of this scheme is the Two Complement Inversion. Every Number can have it's sign changed by first inverting all bits, and then adding One. Addition and Subtraction using that scheme works correctly all the time. It is so good, the machine is not interested in whether a byte is signed or unsigned! It uses the same mechanism to do arithmetic for both!

A Byte of value 0xFF will per definition always be interpreted as 255 by the compiler if it is of unsigned type. It will also always be interpreted by the compiler as -1, if it is of signed type.

Actually, an Unsigned 32 bit Int initialised to -1, would have the value 4294967295, the same as an Unsigned Byte initialised to -1 would have the value of 255. The Compiler is friendly! If you initialise a signed byte with 255, it's value will be -1!

There is hence absolutely no point in testing an unsigned integer for being negative! It has no capacity of being negative! A half decent compiler will probably optimise the test for this condition out! An Unsigned Integer is always, and, per definition, equal or larger than 0. I hope I managed to explain in the above as to WHY!

As to your problem of access violations,

After a Brief look at your code: (unsigned int32)-1 means for the compiler: 4294967295.
So Your essentially loop says for(i=0; i<4294967295;i++){...} Make your iterator Signed! Tell me how you get on after that!

//This is the thing that caught me off guard. "uint_neg_1 < 0" does not evaluate to true.

And that is correct. An unsigned number can only have positive values in the range 0 to infinity. The main point here is that you must follow the rules of mathematics and logic. If you declare a numeric variable as unsigned then that is how it will be treated, and it will never be considered to have a negative value (even if it does have the sign bit set). The compiler will add code to manipulate the value in such a way that any 'negativeness' is always ignored.

It seems like in this signed/unsigned case typecasting allows you to change the way the variable is evaluated in expressions. I think that is typical of typecasting in general, it changes interpretation.

On the other hand I think if you typecast to a data type with a different size it does not just affect the expression but also the raw value.