Most of my code involves passing address of a memory location to several macros which does the required job.
Could you please explain which is the best way to pass the address in terms of a time efficiency.
Sample code:
#define FILL_VAL(ptr /* uint8_t* */ ) \
do \
{ \
/* Macro which does the job */ \
\
}while(0);
uint8_t *buf = malloc(100);
uint16_t buf_index = 0;
//Method 1:
FILL_VAL(&buf[buf_index])
//Method 2:
FILL_VAL( buf + buf_index)
Macros / defines are just text substitutions. And as such, they can not directly influence "time/space/whatever efficiency" of the target program.
So basically your question must be rephrased as "will my compiler generate same code for (similar) expressions containing buf + buf_index and &buf[buf_index]"?
Actually, only live experiments can proof this, but it's a very reasonable guess that the generated code will be the same.
In C++ &buf[buf_index] is preferred.
In C buf + buf_index is normal.
Why??
In C, it's part of the definition of the idiom. "Why say say things with more words than possible?". Say it in the shortest possible way, it makes it easier to understand and harder to type wrong.
C++ Introduced containers. These are data structures that "look" like something they are not. To illustrate this, consider a piece of code that uses a fixed-size C-array.
int my_vec[FIXED_SIZE]; // create elements
FILL_VAL(&my_vec);
Later you want to switch to a variable size array.
std::vector<int> my_vec(FIXED_SIZE); // create a container for elements
FILL_VAL(&my_vec); // << WRONG!!!
Now your "FILL_VAL" macro does the wrong thing. it will write over the actual vector, almost certainly creating a bad pointer, and eventually memory corruption. This is why very early in the use of C++ most programmers switched to this style.
std::vector<int> my_vec(FIXED_SIZE); // create a container for elements
FILL_VAL(&my_vec[0]); // << Works for c-array and vector!
As for which is faster, they express exactly the same thing. Compilers will treat these as exactly the same thing. It is not unusual for compilers to start with a pass that swaps equivalent code for a single standard representation. This way the code generation pass can be simpler.
Related
I've been trying to learn a bit about reverse engineering and how to essentially wrap an existing class (that we do not have the source for, we'll call it PrivateClass) with our own class (we'll call it WrapperClass).
Right now I'm basically calling the constructor of PrivateClass while feeding a pointer to WrapperClass as the this argument...
Doing this populates m_string_address, m_somevalue1, m_somevalue2, and missingBytes with the PrivateClass object data. The dilemma now is that I am noticing issues with the original program (first a crash that was resolved by adding m_u1 and m_u2) and then text not rendering that was fixed by adding mData[2900].
I'm able to deduce that m_u1 and m_u2 hold the size of the string in m_string_address, but I wasn't expecting there to be any other member variables after them (which is why I was surprised with mData[2900] resolving the text rendering problem). 2900 is also just a random large value I threw in.
So my question is how can we determine the real size of a class that we do not have the source for? Is there a tool that will tell you what variables exist in a class and their order (or atleast the correct datatypes or datatype sizes of each variable). I'm assuming this might be possible by processing assembly in an address range into a semi-decompiled state.
class WrapperClass
{
public:
WrapperClass(const wchar_t* original);
private:
uintptr_t m_string_address;
int m_somevalue1;
int m_somevalue2;
char missingBytes[2900];
};
WrapperClass::WrapperClass(const wchar_t* original)
{
typedef void(__thiscall* PrivateClassCtor)(void* pThis, const wchar_t* original);
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
}
So my question is how can we determine the real size of a class that
we do not have the source for?
You have to guess or logically deduce it for yourself. Or just guess. If guessing doesn't work out for you, you'll have to guess again.
Is there a tool that will tell you what variables exist in a class and
their order (or atleast the correct datatypes or datatype sizes of
each variable) I'm assuming by decompiling and processing assembly in
an address range.
No, there is not. The type of meta information that describes a class, it's members, etc. simply isn't written out as the program does not need it nor are there currently no facilities defined in the C++ Standard that would require a compiler to generate that information.
There are exactly zero guarantees that you can reliably 'guess' the size of a class. You can however probably make a reasonable estimate in most cases.
The one thing you can be sure of though: the only problem is when you have too little memory for a class instance. Having too much memory isn't really a problem at all (Which is what adding 2900 extra bytes works).
On the assumption that the code was originally well written (e.g. the developer decided to initialise all the variables nicely), then you may be able to guess the size using something like this:
#define MAGIC 0xCD
// allocate a big buffer
char temp_buffer[8092];
memset(temp_buffer, MAGIC, 8092);
// call ctor
PrivateClassCtor PrivateClassCtorFunc = PrivateClassCtor(DLLBase + 0x1c00);
PrivateClassCtorFunc(this, original);
// step backwards until we find a byte that isn't 0xCD.
// Might want to change the magic value and run again
// just to be sure (e.g. the original ctor sets the last
// few bytes of the class to 0xCD by coincidence.
//
// Obviously fails if the developer never initialises member vars though!
for(int i = 8091; i >= 0; --i) {
if(temp_buffer[i] != MAGIC) {
printf("class size might be: %d\n", i + 1);
break;
}
}
That's probably a decent guess, however the only way to be 100% sure would be to stick a breakpoint where you call the ctor, switch to assembly view in your debugger of choice, and then step through the assembly line by line to see what the max address being written to is.
Say I want to store the size of a std::vector in an int I have the following options, to my knowledge:
int size = vector.size(); // Throws an implicit conversion warning
int size = (int)vector.size(); // C like typecasting is discouraged and forbidden in many code standards
int size = static_cast<int>(vector.size()); // This makes me want to gouge my eyes out (it's ugly)
Is there any other option that avoids all of the above issues?
I'm going to frame challenge this question. You shouldn't want a short and elegant solution to this problem.
Casting in any language, including C++, is basically the programmer's equivalent to swearing: you'll do it sometimes because it's easy and effortless, but you shouldn't. It means that somewhere, somehow, your design got screwed up. Maybe you need to pass the size of an array to an old API, but the old API didn't use size_t. Maybe you designed a piece of code to use float's, but in the actual implementation, you treat them like int's.
Regardless, casting is being used to patch over mistakes made elsewhere in the code. You shouldn't want a short and simple solution to resolve that. You should prefer something explicit and tedious, for two reasons:
It signals to other programmers that the cast isn't a mistake: that it's something intentional and necessary
To make you less likely to do it; and to instead focus on making sure your types are what you intended, rather than what the target API is expecting.
So embrace the static_cast, dynamic_cast, const_cast, and reinterpret_cast style of writing your code. Instead of trying to find ways to make the casts easier, find ways to refactor your code so they're less necessary.
If you're prepared to disregard all of that instead, then write something like this:
template<typename T, typename U>
T as(U && u) {
return static_cast<T>(u);
}
int size = as<int>(values.size());
bool poly_type::operator==(base_type const& o) {
if(this == &o)
return true;
if(typeid(*this) == typeid(o)) {
return as<poly_type const&>(o).value == value;
} else {
return false;
}
}
That'll at least reduce the amount of typing you end up using.
I'm going to answer your question just like you've asked. The other answers say why you shouldn't do it. But if you still want to have this, use this function:
#include <assert.h>
#include <limits.h>
inline int toInt(std::size_t value) {
assert(value<=MAX_INT);
return static_cast<int>(value);
}
Usage:
int size = toInt(vector.size());
toInt asserts if the input value is out of range. Feel free to modify it to your needs.
Storing a vector size , which might exceed the maximum value of int, in an int is an ugly operation in the first place. This is reflected in your compiler warning or the fact that you have to write ugly code to suppress the warning.
The presence of the static_cast informs other people reading the code that there is a potential bug here, the program might malfunction in various ways if the vector size does exceed INT_MAX.
Obviously (I hope?) the best solution is to use the right type for the value being stored, auto size = vector.size();.
If you really are determined to use int for whatever reason then I would recommend adding code to handle the case of the vector begin too large (e.g. throw before the int declaration if it is), or add a code comment explaining why that was never possible.
With no comments, the reader can't tell if your cast was just because you wanted to shut the compiler up and didn't care about the potential bug; or if you knew what you were doing.
Instead of limiting my arrays index one by one...
int limit=10, data_1[10], data_2[10], data_3[10];
Is it possible to use the value of limit to limit the indeces of these datas? My code gets an error "Constant Expression Required" when I use data_1[limit]
Any solutions to use another variable to limit these arrays' indeces in C++?
Here you go:
const int limit = 10;
int data_1[limit], data_2[limit], data_3[limit];
limit must be a const
EDIT:
As other answers have mentioned, limit could also simply be defined through a preprocessing step, like so:
#define LIMIT 10 // Usually preprocessor-defined variables are in all caps
The error message is telling you that you must have a constant expression to allocate memory on the stack. For allocating on the stack you have two options (for getting a constant); you could use
#define LIMIT 10
or you could use const int like this
const int LIMIT = 10;
and with either, this would then work
int data_1[LIMIT], data_2[LIMIT], data_3[LIMIT];
You might also allocate on the heap (using malloc()), but then you must also call free().
int *data = (int *) malloc(limit * sizeof(int)); /* as an example */
/* Do something, check that malloc succeeded */
free(data); /* free the memory */
You've tagged this with both C and C++, but the right way to handle this is different between the two.
In C, assuming a reasonably up-to-date (C99 or newer) compiler, the way you've done things is allowed, as long as data_1, data_2 and data_3 are local to some function. They almost certainly shouldn't be globals, so for C the obvious cure is to simply make them local to the function that needs them (and if other functions need them, pass them as parameters).
In C++, you've gotten some answers that cure the immediate problem, such as const-qualifying limit and allocating the other three items dynamically. At least in my opinion, these are inferior choices though. In most cases, you should use std::vector instead of arrays, in which case you don't need to const-qualify limit for things to be just fine:
int limit = 10;
std::vector<int> data_1(limit), data_2(limit), data_3(limit);
use a macro or const
#define LIMIT 10
or
const int LIMIT = 10;
for C and C++
#define LIMIT 10
int data[LIMIT];
just for just C++
const int LIMIT = 10;
int data[LIMIT];
Seeing the number of answers that propose to use a #define, and as the Q is tagged C++, I think it should be mentioned, though, that using a #define has drawbacks, especially the fact that the compiler doesn't know what LIMIT is, as every occurences are removed during the preprocessing stage and replaced with the value. Thus, when debugging, you could get an error message referring to the value (i.e. 10 in this case) but no mention of LIMIT, as it never entered the symbol table.
Thus, you should prefer the use of
const int Limit = 10;
int data[Limit];
instead of
#define LIMIT 10
if you're given the opportunity (i.e. if you're in C++, and not in C).
And as mentioned, using an std::vector would be simpler and would remove the need for such constant expression.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
C++ - enum vs. const vs. #define
Before I used #define I used to create constants in my main function and pass them where they were needed. I found that I passed them very often and it was kind of odd, especially array sizes.
More recently I have been using #define for the reason that I don't have to pass constants in my main to each individual function.
But now that I think of it, I could use global constants as well, but for some reason I have been a little hesitant towards them.
Which is the better practice: global constants or #define?
A side question, also related: Is passing constants from my main as I described a bad practice?
They don't do quite the same thing. #define lets you affect the code at compilation time, while global constants only come into effect at runtime.
Seeing as #define can only give you extra trouble because there's no checking going on with how you use it, you should use global constants when you can and #define when you must. It will be safer and more readable that way.
As for passing constants from main, it's not unreasonable because it makes the called functions more flexible to accept an argument from the caller than to blindly pull it out of some global. Of course it the argument isn't really expected to change for the lifetime of the program you don't have much to gain from that.
Using constants instead of #define is very much to be preferred. #define replaces the token dumbly in every place it appears, and can cause all sorts of unintended consequences.
Passing values instead of using globals is good practice. It makes the code more flexible and modular, and more testable. Try googling for "parameterise from above".
You should never use either #defines or const variables to represent array sizes; it's better to make them explicit.
Instead of:
#define TYPICAL_ARRAY_SIZE 4711
int fill_with_zeroes(char *array)
{
memset(array, 0, TYPICAL_ARRAY_SIZE);
}
int main(void)
{
char *za;
if((za = malloc(TYPICAL_ARRAY_SIZE)) != NULL)
{
fill_with_zeroes(za);
}
}
which uses a (shared, imagine it's in a common header or something) #define to communicate the array size, it's much better to just pass it to the function as a real argument:
void fill_with_zeroes(char *array, size_t num_elements)
{
memset(array, 0, num_elements); /* sizeof (char) == 1. */
}
Then just change the call site:
int main(void)
{
const size_t array_size = 4711;
char *za;
if((za = malloc(array_size)) != NULL)
{
fill_with_zeroes(za, array_size);
}
}
This makes the size local to the place that allocated it, there's no need for the called function to magically "know" something about its arguments that is not communicated through its arguments.
If the array is non-dynamically allocated, we can do even better and remove the repeated symbolic size even locally:
int main(void)
{
char array[42];
fill_with_zeroes(array, sizeof array / sizeof *array);
}
Here, the well-known sizeof x / sizeof *x expression is used to (at compile-time) compute the number of elements in the array.
Constants are better. The only difference between the two is that constants are type-safe.
You shouldn't use values defined with #define like const parameters. Defines are used mostly to prevent the compiler to compile some parts of code depending on your needings at compile time (platform dependent choices, optimization at compile time, ).
So if you are not using define for these reasons avoid that and use costant values.
I have a function foo(int[] nums) which I understand is essentially equivalent to foo(int* nums). Inside foo I need to copy the contents of the array pointed to by numsinto some int[10] declared within the scope of foo. I understand the following is invalid:
void foo (int[] nums)
{
myGlobalArray = *nums
}
What is the proper way to copy the array? Should I use memcpy like so:
void foo (int[] nums)
{
memcpy(&myGlobalArray, nums, 10);
}
or should I use a for loop?
void foo(int[] nums)
{
for(int i =0; i < 10; i++)
{
myGlobalArray[i] = nums[i];
}
}
Is there a third option that I'm missing?
Yes, the third option is to use a C++ construct:
std::copy(&nums[0], &nums[10], myGlobalArray);
With any sane compiler, it:
should be optimum in the majority of cases (will compile to memcpy() where possible),
is type-safe,
gracefully copes when you decide to change the data-type to a non-primitive (i.e. it calls copy constructors, etc.),
gracefully copes when you decide to change to a container class.
Memcpy will probably be faster, but it's more likely you will make a mistake using it.
It may depend on how smart your optimizing compiler is.
Your code is incorrect though. It should be:
memcpy(myGlobalArray, nums, 10 * sizeof(int) );
Generally speaking, the worst case scenario will be in an un-optimized debug build where memcpy is not inlined and may perform additional sanity/assert checks amounting to a small number of additional instructions vs a for loop.
However memcpy is generally well implemented to leverage things like intrinsics etc, but this will vary with target architecture and compiler. It is unlikely that memcpy will ever be worse than a for-loop implementation.
People often trip over the fact that memcpy sizes in bytes, and they write things like these:
// wrong unless we're copying bytes.
memcpy(myGlobalArray, nums, numNums);
// wrong if an int isn't 4 bytes or the type of nums changed.
memcpy(myGlobalArray, nums, numNums);
// wrong if nums is no-longer an int array.
memcpy(myGlobalArray, nums, numNums * sizeof(int));
You can protect yourself here by using language features that let you do some degree of reflection, that is: do things in terms of the data itself rather than what you know about the data, because in a generic function you generally don't know anything about the data:
void foo (int* nums, size_t numNums)
{
memcpy(myGlobalArray, nums, numNums * sizeof(*nums));
}
Note that you don't want the "&" infront of "myGlobalArray" because arrays automatically decay to pointers; you were actually copying "nums" to the address in memory where the pointer to the myGlobalArray[0] was being held.
(Edit note: I'd typo'd int[] nums when I mean't int nums[] but I decided that adding C array-pointer-equivalence chaos helped nobody, so now it's int *nums :))
Using memcpy on objects can be dangerous, consider:
struct Foo {
std::string m_string;
std::vector<int> m_vec;
};
Foo f1;
Foo f2;
f2.m_string = "hello";
f2.m_vec.push_back(42);
memcpy(&f1, &f2, sizeof(f2));
This is the WRONG way to copy objects that aren't POD (plain old data). Both f1 and f2 now have a std::string that thinks it owns "hello". One of them is going to crash when they destruct, and they both think they own the same vector of integers that contains 42.
The best practice for C++ programmers is to use std::copy:
std::copy(nums, nums + numNums, myGlobalArray);
Note per Remy Lebeau or since C++11
std::copy_n(nums, numNums, myGlobalArray);
This can make compile time decisions about what to do, including using memcpy or memmove and potentially using SSE/vector instructions if possible. Another advantage is that if you write this:
struct Foo {
int m_i;
};
Foo f1[10], f2[10];
memcpy(&f1, &f2, sizeof(f1));
and later on change Foo to include a std::string, your code will break. If you instead write:
struct Foo {
int m_i;
};
enum { NumFoos = 10 };
Foo f1[NumFoos], f2[NumFoos];
std::copy(f2, f2 + numFoos, f1);
the compiler will switch your code to do the right thing without any additional work for you, and your code is a little more readable.
For performance, use memcpy (or equivalents). It's highly optimised platform-specific code for shunting lots of data around fast.
For maintainability, consider what you're doing - the for loop may be more readable and easier to understand. (Getting a memcpy wrong is a fast route to a crash or worse)
Essentially, as long as you are dealing with POD types (Plain Ol' Data), such as int, unsigned int, pointers, data-only structs, etc... you are safe to use mem*.
If your array contains objects, use the for loop, as the = operator may be required to ensure proper assignment.
A simple loop is slightly faster for about 10-20 bytes and less (It's a single compare+branch, see OP_T_THRES), but for larger sizes, memcpy is faster and portable.
Additionally, if the amount of memory you want to copy is constant, you can use memcpy to let the compiler decide what method to use.
Side note: the optimizations that memcpy uses may significantly slow your program down in a multithreaded environment when you're copying a lot of data above the OP_T_THRES size mark since the instructions this invokes are not atomic and the speculative execution and caching behavior for such instructions doesn't behave nicely when multiple threads are accessing the same memory. Easiest solution is to not share memory between threads and only merge the memory at the end. This is good multi-threading practice anyway.