Run time penalty in Variable Length arrays? - c++

Reference to the Stackoverflow question title "variable length arrays in C++" we know that following is valid
void foo(int n) {
int values[n]; //Declare a variable length array
}
I have read that there exists a small run time penalty(in variable length arrays) here. Can somebody nicely explain what that is in this context?
I would also try my level best to locate the link where I read it.I apologize i could not mention it here.

IIRC, with GCC, functions with VLA's:
Will not be inlined
Need to use an extra register for the frame pointer (that is, -fomit-frame-pointer works on non-VLA functions), so there is one less register available for the other work the function needs to do.

Related

small classes how to pass by value and register

I need to use small classes formed essentially from just an integer "handle" and be able to treat that as a class in order to be able to attach methods to it.
At the same time I want also to avoid to pass from one function to the other just the address of the handle ( the "this" pointer) because doing so means that in order to read a handle that should just be there I would need to read a memory location to have it.
So I need essentially to have the "handle" passed by value eventually in registers ( depending on calling convention ).
Some clarifying code is:
struct F{
int aa,bb,cc;};
F A[0x100];
struct handle{
int hhh;
void elaborateHandle(){ ... operations ;}
};
int main(){
handle h;h.hhh=3;
h.elaborateHandle();
// I need that call to pass on the stack essentially the number 3 and not the address of where the number 3 was saved on the stack.
}
I think, that you shouldn't think about it, because here you are having a very very small performance lose, dereferencing one pointer is a cheap operation.
If you use optimizing compiler, there is a chance, that your method call will be inlined inside caller func.
Anyways, if you trying to optimize your performance, you should search in other place.
But if you really thinking that it causes troubles there is a way:
Declare the function outside your class (not as member), and if you want to access private data declare it as friend.
First, print the assembly language of the code that calls your function and the first part of your function.
The assembly language will show how the registers are used. Normally, compilers try to make best use of registers when passing values to functions.
To help the compiler better use registers:
Limit parameter quantities in functions.
The compiler reserves a limited quantity of registers for passing to functions. The more parameters a function has, the less probability that all parameters will be in registers.
Also, the compiler may need to save registers before calling a function in order to pass more parameters to the function.
Pass values that fit inside registers.
If the compiler can't fit a data type in one register, it may use two registers (such as passing 64 bit values on a 32-bit processor).
If the compiler can't fit the data type in two registers, it may push the data on the stack rather than passing by register. This means that the receiving function will have to copy the values from the stack.
Pass large items by reference or pointer. On most platforms, the compiler can store a pointer into a register and pass the register to the receiving function. A lot faster that pushing and popping values with a stack. Also, compilers may use pointers to implement references.
Suggest to the compiler to place values in registers.
Although the register keyword may not be available in more recent language versions, using the register keyword with variables suggests to the compiler that you would like to have the variable in a register. It is only a suggestion and the compiler can ignore it and you.
Define variables as close to their point of usage. This allows the compiler to allocate registers when needed rather than reserving them for a while.
Create scope blocks. Using { and } to create new scope blocks will help the compiler allocate and deallocate registers that are used only in a limited area. So if variables are only used in a limited area in a function, place that area in a new scope block. You can even tag those local variable with the register keyword.
Compile with high optimization levels.
Set your compiler's optimization levels high, then check the assembly language.
The compiler may use memory for variable storage when optimization is at the lowest setting (debugging). At higher optimization levels, the compiler starts using registers more effectively.
Remember, print the assembly language of the functions and the calling code before and after playing with optimization levels.
Using the g++ compiler on the x86 platform, I found that the flag "-freg-struct-return" has a different effect that described in the documentation. According to my tests, that flag, obliges the compiler to pass structures by value ( I didn't checked it but it will be probably be valid when structures have a size smaller than a specific size -- I checked up to 64 bits and it works compiling using -m32 ).
Differently from what the documentation says, structs aren't passed in registers, unless a register passing convention in used.
That behaviour is valid also for declared or compiler recognized const methods of structures ( or classes ).
So if a method doesn't change the structure, than the structure is passed by value ( in stack allocated space or in registers depending e.g. on defining a function using the __attributes__ (( regparam(3) )) .
Instead as it should be, if a structure is modified by a method, than the address is passed to the method instead of the value of the struct ( as it should be ).
The documentation of that flag is misleading because it says: "Return struct and union values in registers when possible. This is more efficient for small structures than -fpcc-struct-return.
If you specify neither -fpcc-struct-return nor -freg-struct-return, GCC defaults to whichever convention is standard for the target. If there is no standard convention, GCC defaults to -fpcc-struct-return, except on targets where GCC is the principal compiler. In those cases, we can choose the standard, and we chose the more efficient register return alternative."
The testing code I used is bellow, the effects may be seen by seeing what the disassemler shows.
#include <stdio.h>
int a;
int aa[100];
struct Token{
short int ind; short int ind1; short int ind2;
int v() const{return aa[ind];}
__attribute((noinline)) void setind(int i){ind=i;}
__attribute((noinline)) int tok() {return ind;}
};
__attribute__ ((noinline)) void showIt(Token t){
t.ind+=t.ind;
a+=t.ind;
t.ind=8;
}
Token t0 = {.ind=15};
Token t1 = {.ind=99};
int main(int argc, char **argv)
{
t0.setind(10);
int x=19;
x=t0.tok();
showIt(t0);
t1.setind(20+x);
showIt(t1);
printf("%i\n",a);
return 0;
}

Static keyword saves value returned by function?

I have several functions in a program I'm writing that use a value I need to calculate with a very slow function. This value will change every time the program is rerun, so I can't just store a static value. Below is an example.
void this_gets_called_frequently()
{
static int value = slow_function();
//do stuff with the above value
}
My main problem here is not one of the program not working, rather of neatness. I don't really want to initialise a global variable and store the value in that, since it is not going to change once calculated. Would using the static keyword in the manner shown above only call the function above to be calculated once? Would a const keyword added in there help?
Thanks everyone, this was answered perfectly!
Yes, an initialization of local static variable will happen at most once (although I recall some compiler versions could have problems with multithreading here).
const is not required, in this case it's mostly a matter of readability and taste.
Would using the static keyword in the manner shown above only call the function above to be calculated once?
Yes, on the first invocation of this_gets_called_frequently
Would a const keyword added in there help?
No. But add const for documentation value.
Use may use the thread local variables from C++11, if they are available in your compiler. If you are on Windows, you can use similar TlsAlloc API. It is there since the dawn of Win32.

How local constants are stored in c++ library files

I am writing a library where I need to use some constant integers. I have declared constant int as a local variable in my c function e.g. const int test = 45325;
Now I want to hide this constant variable. What it means is, if I share this library as a .so with someone, he should not be able to find out this constant value ?
Is it possible to hide constant integers defined inside a library ? Please help
Here is my sample code
int doSomething()
{
const int abc = 23456;
int def = abc + 123;
}
doSomething is defined as local function in my cpp file. I am referring this constant for some calculations inside the same function.
If I understand right, you're not so much worried about an exported symbol (since it's a plain normal local variable, I'd not worry about that anyway), but about anyone finding out that constant at all (probably because it is an encryption key or a magic constant for a license check, or something the like).
This is something that is, in principle, impossible. Someone who has the binary code (which is necessarily the case in a library) can figure it out if he wants to. You can make it somewhat harder by calculating this value in an obscure way (but be aware of compiler optimizations), but even so this only makes it trivially harder for someone who wants to find out. It will just mean that someone won't see "mov eax, 45325" in the disassembly right away, but it probably won't keep someone busy for more than a few minutes either way.
The constant will always be contained in the library in some form, even if it is as instructions to load it into a register, for the simple reason that the library needs it at runtime to work with it.
If this is meant as some sort of a secret key, there is no good way to protect it inside the library (in fact, the harder you make it, the more people will consider it a sport to find it).
The simplest is probably to just do a wrapper class for them
struct Constants
{
static int test();
...
then you can hide the constant in the .cpp file
You can declare it as
extern const int test;
and then have it actually defined in a compilation unit somewhere (.cpp file).
You could also use a function to obtain the value.

I have lots of questions about c++ that are really confusing me

I started learning c++ about 3 weeks ago after 2 years of java. It seems so different but im getting there. my lecturer is a lovely guy but any time i ask a question as to why something is that way or this way. he just responds "because it is".
Theres lots of comments in the code below with a few random questions, but the main problem is im getting two build errors, one says the arraytotal has not been initialized (even though i found a value for it) and the other says an external reference in main.
would anyone mind reading the code and answering a few comments within, and maybe the overall problem im having?
#include<string>
#include<fstream>
#include<ostream>
using namespace std;
//double decimals[5] ={2,4,6,8,10};
const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?
//double decimals[arraySize];
/*
this array is being created in the function averageN() but why?
cant i just create it up top and reference it in?
*/
// why do you have to write the name of the function up here before you even create it?
double averageN();
int main()
{
averageN();
return 0;
}
// why does the array have to be created here?
double averageN(double decimals[arraySize])
{
double average;
double arrayTotal;
for (int i = 0; i<5;i++)
{
// fills with random numbers from 0 - 10
decimals[i] = (0+(rand()%10));
}
// find the total of all the elements in the array
for (int i = 0; i < arraySize;i++)
{
double currentElement = decimals[i];
arrayTotal = (currentElement+arrayTotal);
//arrayTotal +=decimals[i]) ;
}
// return the average
average = (arrayTotal/arraySize);
return 0.0;
}
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?
Yes, it has to be const, moreover, it must be a constant expression, which means its size must be known at compile-time (not at runtime).
If you want to resize arrays, then the best is to use the standard container std::vector. Or use dynamically allocated arrays if you want a fixed-size array, but the size is not known until runtime
/*
this array is being created in the function averageN() but why?
cant i just create it up top and reference it in?
*/
if you speak about decimals, then no, it is a global variable, you can use it from anywhere.
// why do you have to write the name of the function up here before you even create it?
You must declare any name in C++ prior to its use. Since you call this function in main, it must be at least declared beforehand. You can also provide the definition (body) before main.
// why does the array have to be created here?
Oops, it appears that there's a big mixup in your code. As a matter of fact, you have 2 functions named averageN, one is averageN that takes no parameters, other is AveraeN taking an array of double.You never defined the first one, just declared.
Errors:
doubleTotal is not initialized. Well it is not
double arrayTotal; change to
double arrayTotal = 0.0;
unresolved extenal in main - that's the AverageN function in main you are caling. You never wrote a body for it. You created a function that takes an array, which wasn't useful since your array is global. Just delete the array parameter from AverageN definition.
HTH
P.S. Read S. Lippmann's C++ Primer. It's the best book for beginners ther is for C++. IMO :)
const gives the compiler a clue that the item should not be changed and if the code attempts it then the compiler can flag an error.
the function name is mentioned before the actual declaration the main() function needs to reference it before the compiler has actually come to compile it (as it later on in the code file). You can move the whole function before the main() to avoid this.
double averageN(double decimals[arraySize]) is saying this function takes an array. It doesn't say that it create the array. If you look in the function, it takes the array, and adds calculated values into it (decimals[i] = (0+(rand()%10))). This function also calculates an average over the array and returns that as a double.
So to answer your big question what's wrong - read the last point and look at the call you are making -averageN(); - can you see how this is not the correct call?
OK, here's your only assignment into arrayTotal:
arrayTotal = (currentElement+arrayTotal);
Now, what is the value of arrayTotal after this assignment? Well, it depends on its value before the assignment. What was its value before the very first assignment? You don't know. It could be anything because you never gave it an initial value.
const int arraySize = 5;
// does an arraySize have to be const always? is it so it doesnt channge after the array has been created?
C++ basically supports two kinds of arrays: fixed-size arrays, that are declared as type name[size], and dynamic arrays that are allocated with new[].
For fixed-size array you must provide their size to the compiler so that it can set aside enough memory for the array. As the size must be known to the compiler, you can only specify it with a const variable or a literal.
Although it is possible to create dynamically allocated arrays yourself, by invoking new[], this will give you some headaches getting the memory management right. It is better to use existing classes that do this for you, like std::vector.
//double decimals[arraySize];
/*
this array is being created in the function averageN() but why?
cant i just create it up top and reference it in?
*/
You can create it up here, but that would give anybody access to the array. For a small program like this that is not a big problem, but consider that there are a dozen other files that can also access the array and change it at unexpected moments.
It is basically the same question as to why you don't make all classes and members public in Java: to limit who has access.
// why do you have to write the name of the function up here before you even create it?
double averageN();
You have to declare the function before you can use it. C++ has the requirement that all names you use must have been declared to the compiler before their first use, and the compiler will read a file in sequential order from the top to the bottom.
Note that this declaration does not match the function definition you give below. As C++ supports function overloading, the two are considered different functions, because they accept different parameters (none versus a pointer)
int main()
{
averageN();
return 0;
}
// why does the array have to be created here?
double averageN(double decimals[arraySize])
{
This does not create an array. Instead it specifies that the function expects to be called with a pointer argument (the arraySize is completely ignored and you can't pass an array to a function in C++, so the parameter is adjusted to read double *decimals).
To get a working program, you need to change the two lines above to
double averageN()
{
double decimals[arraySize];
double average;
double arrayTotal;
Both average and arrayTotal are not initialised. That means they will start with some unknown value.
For average, thatis not a problem, because the first thing you do with it is assign a new value. But for arrayTotal, you are adding values to it, so you must let it start with a known value.
for (int i = 0; i<5;i++)
{
// fills with random numbers from 0 - 10
decimals[i] = (0+(rand()%10));
}
// find the total of all the elements in the array
for (int i = 0; i < arraySize;i++)
{
double currentElement = decimals[i];
arrayTotal = (currentElement+arrayTotal);
//arrayTotal +=decimals[i]) ;
}
// return the average
average = (arrayTotal/arraySize);
return 0.0;
}
My quick answers without double checking (its been awhile since I've developed in C++) are:
arraytotal has not been initialized
I suspect that your compiler flags this as an error to make sure you do it. If you don't, you can't be sure what it will be initialized to. Traditionally for debug builds, C/C++ initialized memory to some debug value to help identify uninitialized variables. Set arrayTotal = 0 when it is initialized and that should go away. (Best practice)
e.g. double arrayTotal = 0;
external reference in main
I suspect this is because your prototype for averageN does not match the method defined later. A prototype needs to include the types of the parameters as well as the return type. Change the prototype from double averageN(); to double averageN(double []); and I believe that will fix that problem.
does an arraySize have to be const always? is it so it doesnt channge after the array has been created?
Since you are using it to define the size of the array passed into averageN, yes. Setting the size of the array like this requires a constant value.
This array is being created in the function averageN() but why?
cant i just create it up top and reference it in?
It is not being created in averageN. It is a formal parameter to averageN. The caller of averageN needs to provide the appropriate variable and pass it in. Then from within the method, you access it through decimals.
why do you have to write the name of the function up here before you even create it?
This is the function prototype. It is necessary if the function is referenced in code before the function is defined. This could be resolved in other ways as well, such as moving the definition of averageN before all uses of it.
Couple of problems:
Your forward declaration of averageN is not correct
Code:
double averageN();
The supplied version below takes a parameter.
Your declaration of averageN does not quite work
Declaring parameters of type array is not intuitively obvious.
Normally people let the array degrade to a pointer to the array and pass a length as a second parameter.
Code:
double averageN(double *decimals, int arraySize)
If you want to only pass arrays of a specific size you need to do so by reference:
double averageN(double (&decimals)[arraySize])
Your call to averageN() in main.
You are passing zero parameters. Now this matches the forward declaration but not the actual definition.
Result I would change the code like this:
extern double averageN(double (&decimals)[arraySize]);
int main()
{
double data[arraySize];
averageN(data);
return 0;
}
// why does the array have to be created here?
double averageN(double (&decimals)[arraySize])
{
In addition to the technical details of the other answers, instead answering the complaint in your first paragraph: one way to get quality answers to "why" C++ questions is to ask in one of the Usenet groups, because, like with StackOverflow there are Real Experts hanging out there, but unlike StackOverflow even a beginner's question is likely to get an answer from a member of the standardization committee, and if you're lucky even from those who have penned the standard (like Andrew Koenig or currently Pete Becker). In earlier times Bjarne was there too. But recent years he hasn't posted much.
Basic novice "why" questions:alt.comp.lang.learn.c-c++. Francis Glassborow hangs out there. He's a committe member and author of several successful C++ introductory books. He also knows a bit of math, and since the posting frequency there is low (what with StackOverflow!), you are almost assured that any halfway interesting question will be answered almost immediately -- and correctly -- by Francis, in a snap. :-)
General questions about the C++ language: comp.lang.c++and/or comp.lang.c++.moderated. The latter group is moderated and has a charter. The moderation reduces noise -- e.g. no spam -- but adds delay. Some committee members prefer to post mostly in the unmoderated group (e.g. James Kanze), some, like Pete Becker and Howard Hinnant, post in both groups, and some well known experts, e.g. Andrei Alexandrescu, now apparently only post in the moderated group.
Questions about what the standard means, reports about errors in the standard and so on (in earlier times this was also where you formally reported defects in the standard): [comp.std.c++]. This is also a moderated group, and unfortunately the mod delay is now almost unbearably long. But as a novice you're probably less interested in the formal details, and more interested in rationales and explanations, for which [comp.lang.c++] and [comp.lang.c++.moderated] are great groups (I think StackOverflow's main advantage is when you're wondering "what's the bug in this code" or questions that in principle can be resolved by just reading the relevant documentation).
Finally, I've linked to Google Groups which provides a web based interface, but you can access these groups more directly from a Usenet client like Thunderbird (or e.g. the Opera browser, which has a built-in client). All you have to do in order to access Usenet via a local client is to configure the client, telling it about a server, like the free EternalSeptember. Or AIOE.
Cheers & hth.,
– Alf
One thing nobody seems to have commented on: your return statement at the end of averageN is wrong. You say you're returning the average, then you calculate the radius, and then return 0.0;. Try return average; or return arrayTotal/arraySize;.

Does an arbitrary instruction pointer reside in a specific function?

I have a very difficult problem I'm trying to solve: Let's say I have an arbitrary instruction pointer. I need to find out if that instruction pointer resides in a specific function (let's call it "Foo").
One approach to this would be to try to find the start and ending bounds of the function and see if the IP resides in it. The starting bound is easy to find:
void *start = &Foo;
The problem is, I don't know how to get the ending address of the function (or how "long" the function is, in bytes of assembly).
Does anyone have any ideas how you would get the "length" of a function, or a completely different way of doing this?
Let's assume that there is no SEH or C++ exception handling in the function. Also note that I am on a win32 platform, and have full access to the win32 api.
This won't work. You're presuming functions are contigous in memory and that one address will map to one function. The optimizer has a lot of leeway here and can move code from functions around the image.
If you have PDB files, you can use something like the dbghelp or DIA API's to figure this out. For instance, SymFromAddr. There may be some ambiguity here as a single address can map to multiple functions.
I've seen code that tries to do this before with something like:
#pragma optimize("", off)
void Foo()
{
}
void FooEnd()
{
}
#pragma optimize("", on)
And then FooEnd-Foo was used to compute the length of function Foo. This approach is incredibly error prone and still makes a lot of assumptions about exactly how the code is generated.
Look at the *.map file which can optionally be generated by the linker when it links the program, or at the program's debug (*.pdb) file.
OK, I haven't done assembly in about 15 years. Back then, I didn't do very much. Also, it was 680x0 asm. BUT...
Don't you just need to put a label before and after the function, take their addresses, subtract them for the function length, and then just compare the IP? I've seen the former done. The latter seems obvious.
If you're doing this in C, look first for debugging support --- ChrisW is spot on with map files, but also see if your C compiler's standard library provides anything for this low-level stuff -- most compilers provide tools for analysing the stack etc., for instance, even though it's not standard. Otherwise, try just using inline assembly, or wrapping the C function with an assembly file and a empty wrapper function with those labels.
The most simple solution is maintaining a state variable:
volatile int FOO_is_running = 0;
int Foo( int par ){
FOO_is_running = 1;
/* do the work */
FOO_is_running = 0;
return 0;
}
Here's how I do it, but it's using gcc/gdb.
$ gdb ImageWithSymbols
gdb> info line * 0xYourEIPhere
Edit: Formatting is giving me fits. Time for another beer.