Basic syntax array declaration - c++

If I am using an int as the array size when declaring a new array lint complains. What is the correct way to resolve this:
I could statically cast int to unsigned but that looks a bit odd...
What is the best way to resolve this without changing the use of an array and the need for integer as size?
MapItemPtr* pMapItems = new MapItemPtr[ (unsigned int)iRecordCount ];
Could do:
MapItemPtr* pMapItems = new MapItemPtr[static_cast<unsigned int>( iRecordCount )];
Is this the correct way to resolve the lint error:
Line 3811 Error 737: Loss of sign in promotion from int to unsigned int
or is there a more elegant way?

Since iRecordCount is clearly intended to hold a nonnegative integer, why not just declare it as unsigned int in the first place?

The error is not the constness of the variable, as the lint said:
: Line 3811 Error 737: Loss of sign in promotion from int to unsigned int.
You have a few options:
1 - static_cast<> int to unsigned int,
2 - (unsigned int*) c-style cast, but that should be avoided in c++ code.
3 - create a temporary unsigned int variable that will create the vector for you.
since you are just creating an array, the type of the variable could be size_t, declared in cstddef.

Related

Cannot convert argument 1 from " unsigned int *" to "size t *"

I am working on Student Project and got SDK from site and building libraries on Visual Studio. Once I build libraries using cmake opened solution in VS and build in VS gives me above error. Not sure how to fix it.
This is proc where I get error.
pmdDllExport int pmdpGetSourceDataDescription (unsigned hnd, PMDDataDescription *result)
{
if (!idOk (hnd))
{
globalErrorMessage = "unknown handle";
return PMD_UNKNOWN_HANDLE;
}
SrcPluginData *dat = g_data[hnd];
int c_channels = 1;
//
dat->currentDD.type = PMD_USER_DEFINED_0; /* USER DEFINE TYPE DATA for O3D3xx data*/
dat->currentDD.subHeaderType = PMD_IMAGE_DATA;
dat->currentDD.img.numSubImages = 6;/* Mentions number of images in image data
buffer. We have six images*/
...
/* Get Size of image data buffer */
**dat->o3d3xxCamera->getFrameDataSize (& (dat->currentDD.size));**
dat->currentDD.PID = hnd;
dat->currentDD.DID = g_did;
/*Output this descriptor to calling function */
memcpy (result , &dat->currentDD, sizeof (PMDDataDescription));
return PMD_OK;
}
When I checked what is o3d3xxCamera->getFrameDataSize defined as it is defined as
int32_t getFrameDataSize (size_t *dataSize);
I looked at many queries and they say better to pass variable as type size_t When I checked what is dat->currentdd its struct. So I am not sure how to change this type to size_t.
/**<local datadescriptor of the current data */
PMDDataDescription currentDD;
struct PMDDataDescription
{
unsigned PID;
unsigned DID;
unsigned type;
unsigned size;
unsigned subHeaderType;
...
Do not be tempted to just reintepret_cast the pointer! That will not do what you want, unless size_t happens to be the same as unsigned int, which varies from platform to platform.
Instead, you'll want to use a temporary, and copy back when you're done:
size_t size = dat->currentDD.size; // this will promote as necessary
dat->o3d3xxCamera->getFrameDataSize(&size);
dat->currentDD.size = size; // write it back
One or other of the assignments may need a static_cast, if sizeof (size_t) differs from sizeof (unsigned int). This is fine, as it will be value-preserving (assuming that the value is representable in both types).
If the types have different sizes, you can't reliably cast!
The receiver will treat the pointer as a pointer to a variable with a different size from what you actually have, and there will be breakage (undefined behavior).
Simply change the structure to have
size_t size;
If you can't change the structure, then of course you can use a temporary for the call, then cast that value into the struct. That will work, assuming you never need the higher precision of size_t of course.
dat->o3d3xxCamera->getFrameDataSize (& (dat->currentDD.size));
This passes the address of dat->currentDD.size as parameter to the getFrameDataSize() function.
PMDDataDescription currentDD;
struct PMDDataDescription
{
unsigned PID;
unsigned DID;
unsigned type;
unsigned size;
currentDD.size is of type unsigned.
int32_t getFrameDataSize (size_t *dataSize);
The function expects the addess of a size_t.
Cannot convert argument 1 from " unsigned int *" to "size t *"
Apparently on your system size_t is typedef'ed to something different than unsigned int, making the two pointers incompatible. This might happen on 64-bit systems, where int is 32bit, but size_t is 64bit.
The easy fix is to simply cast the type (1):
dat->o3d3xxCamera->getFrameDataSize(& ( static_cast< size_t >(dat->currentDD.size) ) );
The Right Thing (tm) would probably (2) be to refactor PMDDataDescription to use size_t for its size member.
(1): I say it's easy, not that it's correct. I have no idea what PMDDataDescription is, what library it might come from, or what it is used for. I do not know what getFrameDataSize() does with its parameter. If it does pointer arithmetics on it, casting will break your application, and there is virtually nothing you can do about it because the two API's involved apparently to not agree on data types. We're looking at a very fragile setup here.
(2): You might not have control over its sources. You might be looking at something that is part of a specified API, i.e. cannot be changed for practical reasons. I'm just sayin' that properly constructed software shouldn't have run into this problem in the first place.
You cannot cast pointers. You should try instead to cast only 'unsigned char' into 'size_t', not 'unsigned char*' and 'size_t*'

C++ Indexing an array of ints using a short

Ok guys I asked a question 15 mins ago and closed it because when I tried a simple test in main(), it worked. However, it does not work in the actual code:
Background, I have an array of unsigned ints which I cannot access via an unsigned short indexer. If I declare an array on the stack it works, but it doesnt work for my array data member.
Here is the array declaration:
typedef unsigned int uint;
class OB{
public:
OB();
void x(unsigned short side_pos);
private:
uint best_p[2];
};
and here's the code where I get the compiler error:
void OB::x(unsigned short side_pos){
unsigned int best_price = best_p[side_pos];
}
If I do:
void OB::x(unsigned short side_pos){
unsigned short something_else = 1;
unsigned int best_price = best_p[something_else];
}
I also get the compiler error, which is:
OB.cpp: In member function ‘void OB::x(short unsigned int)’:
OB.cpp:62:56: error: invalid types ‘unsigned int[short unsigned int]’ for array subscript
unsigned int best_price = best_p[side_pos];
It compiles on my computer. Seems the way to get that error is to use a variable instead of an array. Check the names of your attributes.
Based on intuition and comment hints, you have a local variable best_p (an unsigned int by the looks of it) that's shadowing the member of your class. Thus, best_p[side_pos] will use the local variable, not the data member.
If you want the compiler to catch shadowing, the -Wshadow option should do it. The best thing to do when it does is rename something. Having a convention for data member names (m_<name> is a common one) can also help to prevent both accidental shadowing and thinking about what to rename something to.

C++ static_cast from int* to void* to char* - can you help me to understand this code?

I'm a beginner in C++, and I have problem with understanding some code.
I had an exercise to do, to write function which returns size of int, and do not use sizeof() and reinterpret_cast. Someone gave me solution, but I do not understand how it works. Can you please help me to understand it? This is the code:
int intSize() {
int intArray[10];
int * intPtr1;
int * intPtr2;
intPtr1 = &intArray[1];
intPtr2 = &intArray[2];
//Why cast int pointer to void pointer?
void* voidPtr1 = static_cast<void*>(intPtr1);
//why cast void pointer to char pointer?
char* charPtr1 = static_cast<char*>(voidPtr1);
void* voidPtr2 = static_cast<void*>(intPtr2);
char* charPtr2 = static_cast<char*>(voidPtr2);
//when I try to print 'charPtr1' there is nothing printed
//when try to print charPtr2 - charPtr1, there is correct value shown - 4, why?
return charPtr2 - charPtr1;
}
To summarize what I don't understand is, why we have to change int* to void* and then to char* to do this task? And why we have the result when we subtract charPtr2 and charPtr1, but there is nothing shown when try to print only charPtr1?
First of all, never do this in real-world code. You will blow off your leg, look like an idiot and all the cool kids will laugh at you.
That being said, here's how it works:
The basic idea is that the size of an int is equal to the offset between two elements in an int array in bytes. Ints in an array are tightly packed, so the beginning of the second int comes right after the end of the first one:
int* intPtr1 = &intArray[0];
int* intPtr2 = &intArray[1];
The problem here is that when subtracting two int pointers, you won't get the difference in bytes, but the difference in ints. So intPtr2 - intPtr1 is 1, because they are 1 int apart.
But we are in C++, so we can cast pointers to anything! So instead of using int pointers, we copy the value to char pointers, which are 1 byte in size (at least on most platforms).
char* charPtr1 = reinterpret_cast<char*>(intPtr1);
char* charPtr2 = reinterpret_cast<char*>(intPtr2);
The difference charPtr2 - charPtr1 is the size in bytes. The pointers still point to the same location as before (i.e. the start of the second and first int in the array), but the difference will now be calculated in sizes of char, not in sizes of int.
Since the exercise did not allow reinterpret_cast you will have to resort to another trick. You cannot static_cast from int* to char* directly. This is C++'s way of protecting you from doing something stupid. The trick is to cast to void* first. You can static_cast any pointer type to void* and from void* to any pointer type.
This is the important bit:
intPtr1 = &intArray[1];
intPtr2 = &intArray[2];
This creates two pointers to adjacent ints in the array. The distance between these two pointers is the size of an integer that you're trying to retrieve. However the way that pointer arithmetic works is that if you subtract these two then the compiler will return you the size in terms of ints, which will always be 1.
So what you're doing next is re-casting these as character pointers. Characters are (or de-facto are) 1 byte each, so the difference between these two pointers as character pointers will give you an answer in bytes. That's why you're casting to character pointers and subtracting.
As for via void* - this is to avoid having to use reinterpret_cast. You're not allowed to cast directly from a int* to a char* with static_cast<>, but going via void* removes this restriction since the compiler no longer knows it started with an int*. You could also just use a C-style cast instead, (char*)(intPtr1).
"do not use sizeof() and reinterpret_cast"... nothing's said about std::numeric_limits, so you could do it like that :)
#include <limits>
int intSize()
{
// digits returns non-sign bits, so add 1 and divide by 8 (bits in a byte)
return (std::numeric_limits<int>::digits+1)/8;
}
Pointer subtraction in C++ gives the number of elements between
the pointed to objects. In other words, intPtr2 - intPtr1
would return the number of int between these two pointers.
The program wants to know the number of bytes (char), so it
converts the int* to char*. Apparently, the author doesn't
want to use reinterpret_cast either. And static_cast will
not allow a direct convertion from int* to char*, so he
goes through void* (which is allowed).
Having said all that: judging from the name of the function and
how the pointers are actually initialized, a much simpler
implementation of this would be:
int
intSize()
{
return sizeof( int );
}
There is actually no need to convert to void*, other than avoiding reinterpret_cast.
Converting from a pointer-to-int to a pointer-to-char can be done in one step with a reinterpret_cast, or a C-style cast (which, by the standard, ends up doing a reinterpret_cast). You could do a C-style cast directly, but as that (by the standard) is a reinterpret_cast in that context, you'd violate the requirements. Very tricky!
However, you can convert from an int* to a char* through the void* intermediary using only static_cast. This is a small hole in the C++ type system -- you are doing a two-step reinterpret_cast without ever calling it -- because void* conversion is given special permission to be done via static_cast.
So all of the void* stuff is just to avoid the reinterpret_cast requirement, and would be silly to do in real code -- being aware you can do it might help understanding when someone did it accidentally in code (ie, your int* appears to be pointing at a string: how did that happen? Well, someone must have gone through a hole in the type system. Either a C-style cast (and hence a reinterpret_cast), or it must have round-tripped through void* via static_cast).
If we ignore that gymnastics, we now have an array of int. We take pointers to adjacent elements. In C++, arrays are packed, with the difference between adjacent elements equal to the sizeof the elements.
We then convert those pointers to pointers-to-char, because we know (by the standard) that sizeof(char)==1. We subtract these char pointers, as that tells us how many multiples-of-sizeof(char) there are between them (if we subtract int pointers, we get how many multiples-of-sizeof(int) there are between them), which ends up being the size of the int.
If we try to print charPtr1 through std::cout, std::cout assumes that our char* is a pointer-to-\0-terminated-buffer-of-char, due to C/C++ convention. The first char pointed to is \0, so std::cout prints nothing. If we wanted to print the pointer value of the char*, we'd have to cast it to something like void* (maybe via static_cast<void*>(p)).
Please read this: richly commented.
int intSize()
{
int intArray[2]; // Allocate two elements. We don't need any more than that.
/*intPtr1 and intPtr2 point to the addresses of the zeroth and first array elements*/
int* intPtr1 = &intArray[0]; // Arrays in C++ are zero based
int* intPtr2 = &intArray[1];
/*Note that intPtr2 - intPtr1 measures the distance in memory
between the array elements in units of int*/
/*What we want to do is measure that distance in units of char;
i.e. in bytes since once char is one byte*/
/*The trick is to cast from int* to char*. In c++ you need to
do this via void* if you are not allowed to use reinterpret_cast*/
void* voidPtr1 = static_cast<void*>(intPtr1);
char* charPtr1 = static_cast<char*>(voidPtr1);
void* voidPtr2 = static_cast<void*>(intPtr2);
char* charPtr2 = static_cast<char*>(voidPtr2);
/*The distance in memory will now be measure in units of char;
that's how pointer arithmetic works*/
/*Since the original array is a contiguous memory block, the
distance will be the size of each element, i.e. sizeof(int) */
return charPtr2 - charPtr1;
}

Aliasing to an array

I have an object that has an array attribute, say (*obj).some_array;, where some_array is an integer array.
I know that we can alias simply like so:
int test = 10;
int &alias = test;
However, how can I alias to an array of an object, similarly to above but for obj's some_array?
If obj->some_array is of type int[LEN] you can just do:
int (&alias)[LEN] = obj->some_array;
To understand this weird syntax you could use theClockwise/Spiral Rule, a way you could read declarations you're not familiar it (see here).
int &alias[LEN] (which is the same as int &(alias[LEN]) would be an array of LEN references to int.
int (&alias)[LEN] is, instead, a reference to an array of LEN ints
Note that what you call alias is called a reference in C++!
Assuming some_array is an integer array:
int *alias = obj.some_array;

Return dynamic array in C++

I need to return a unsigned int* from a function. The code below will compile but will crash at run time on a Windows 64 bit machine. I know I am making a silly mistake somewhere and can someone point it out for me. :p. I also have declared the function in my header, so I know its not that error.
Please note I have censored the variable names and numbers because the problem in which this function resides is not for public release yet.
Function:
unsigned int* convertTime(unsigned int inputInteger, unsigned short inputFrac) {
unsigned int* output = new unsigned int[2];
double messageTimeFraction = double(inputFrac) * 20e-6;
output[1] = unsigned int(inputInteger + 2209032000);
output[2] = unsigned int(messageTimeFraction * 2e32);
return output; // Seconds
}
Implementation:
unsigned int* timeStamp;
timeStamp = convertTime(inputInteger,inputFrac);
Well, for starters you have output[1] and output[2]. Arrays are zero-indexed in c/c++, so these should be: output[0] and output[1].
But, since you're asking about c++... I urge you to use std::vector or std::pair.
(Of course, for readability's sake, you might just want to use a trivial struct with useful field names)
I know I am making a silly mistake
somewhere and can someone point it out
for me
Sure, and it has nothing to do with the Q's subject:
output[2] = unsigned int(inputFrac * 2e32);
The correct entries in output are [0] and [1] -- you're indexing out of bounds. "Undefined behavior" results (such as, the crash you observe).
The indexes in an array of 2 elements are array[0] and array[1], so change it to:
output[0] = unsigned int(inputInteger + 2209032000);
output[1] = unsigned int(inputFrac * 2e32);
use output[0] and output[1], C / C++ arrays are 0 - based
Arrays in C++ are zero based, so the elements of your array of size two are output[0] and output[1]
You also might want to return something that better represents the data you are returning, such as a struct with seconds and fractional_seconds members rather than creating a new array.
It's also somewhat strange what you are doing -- 2209032000 is the number of seconds in 70 years, and the result of multiplying a short by 2e32 will overflow the size of unsigned int.
The more usual way to write functions like this in a C style is to pass in the reference to the variable that will be set.
As a convenience you return the output buffer so that the function can easily be used in an expression.
unsigned int* convertTime(unsigned int* output, unsigned int inputInteger, unsigned short inputFrac) {
double messageTimeFraction = double(inputFrac) * 20e-6;
output[0] = unsigned int(inputInteger + 2209032000);
output[1] = unsigned int(inputFrac * 2e32);
return output; // Seconds
}
// later
unsigned int seconds[2];
unsigned int* pseconds;
pseconds = convertTime(seconds,a,b);
I created a time structure for the various formats and wrote converter functions to handle the conversions. By using structures, I do not have to worry about memory leaks and improved readability. Furthermore the code is now more scalable than using dynamic arrays, as I can add more fields and create new time formats.
struct time{
unsigned int timeInteger;
unsigned int timeFraction;
}time_X, time_Y;
My silly mistake was the typo of zero-based indexing but the bigger mistake was using dynamic array.