Direct the compiler how to optimize my code - c++

How I can say to the compiler how to optimize something or what some call to function.
I mean like create allocate method and let the compiler optimize it as it optimize it with malloc or new.
Or like if somewhere in the code the function X is called and it's return value is not used then delete this call. (Function from .lib that the compiler don't know a piece about it)
There are options for this?
For example:
auto val=X(); //Use the return value
X(); //Don't use
auto t=allocate<T>(); //Allocate on heap
t->Show(val); //Run single function and don't use it's pointer somewhere (Save it after the function is exit)
And optimize it to:
X(); //First line, just call it
T().Show(val); //Combines third and fourth lines, Allocate on stack and run the single function
If you asking 'why you need this?' I am creating programming language with my own GC and heap. (And lot of things too)
It translates to C++ then I don't want to optimize the code while translate it. (It's gonna be a pain)
Because I can call functions randomly in places. (I can't detect if their values are used or not)

Optimization is compiler-specific, so you'll need to look in your compiler's documentation to see what optimization "hints" it allows you to put in code. For example, here are some of GCC's function attributes:
The malloc attribute tells the compiler that if the function returns a non-null pointer, it's always a "new" area of memory, not another pointer to something that's already been allocated. You'd probably want to use this on a function that wraps the real malloc().
The const attribute (different from the ordinary const keyword) says that the function's return value depends solely on its arguments and has no side effects, so it's safe for the compiler to eliminate duplicate calls with the same arguments.
The noreturn attribute tells the compiler that a function never returns; you'd use this on functions that terminate the program, like C's exit().
Attributes go on the declaration of a function, typically in a header file, so you can use them even if the function's implementation is in a compiled library that'll be linked in later. But remember that function attributes are promises from you to the compiler: if you declare a function with the noreturn attribute, for example, and then implement it with code that actually can return, strange things may happen at runtime when it does.
You can also use function attributes to help with correctness checking:
The nonnull attribute tells the compiler that certain (pointer) arguments aren't supposed to be null, so it can issue warnings if it detects that they might be.
The format argument tells the compiler that the function takes a format string like C's printf(), so it can check that the types of the variadic arguments match the corresponding format codes in the format string. (For example, you shouldn't write "%s" in the format string but then pass an integer as its value.)

Related

How does C++ know how many bytes to copy when retuning an object from a function?

This question popped into my head when I saw the following warning.
struct Wrapper{
char somechar[10];
};
auto returnFoo() {
char somechar[10];
return somechar; // Warning: address of stack memory returned!
}
auto returnFoo() {
Wrapper wpr;
return wpr; // OK
}
I understand the warning. But I don't get why it goes away when I use the wrapper.
I guess the compiler can figure out how big the class is and copy the right amount of bytes but can't do the same for the pointer (char[])??
Where is the "Size" of the class stored (I guess not in the stack since that would be wasteful, maybe in the data segment?)
EDIT:
I think I phrased the question wrong, I know about sizeof and have some experience with CPP. I get that char[] decays to a char*. And I understand that the first example returns a pointer, and the second one returns an object.
What I'm asking is more how the internals of the compiler work.
For the compiler the memory layout is excactly the same (give or take), what it needs to do is copy the array and return it back. It needs to know how many bytes to copy though. My question was, why is it able to figure it out when using an object, but not with a char[]
Functions cannot return arrays in C++. This is simply how the language is specified. This is the same in C.
In the first example, the array name decays to a pointer to first element of the array, and the deduced return type is pointer to char. Pointers can be returned, but the pointer will be invalid because the automatic storage of the pointed object has been deallocated when the function returns.
I don't get why it goes away when I use the wrapper.
When you use the wrapper, you don't return a pointer. You return copy of the local class instance. The array is stored within the class.
I guess the compiler can figure out how big the class is
The compiler knows how the class has been defined, and therefore it knows the size. You can find out what the compiler knows yourself by using sizeof(Wrapper).
Where is the "Size" of the class stored
Depends on language implementation. In a typical case, the compiler will generate instruction for CPU such as "increment stack pointer by 10", because the compiler knows that the size is 10. It knows the size because it knows the definition.
Where is this definition stored (the symbol table, the data segment, the stack, the text segement)?
None of those. You've stored the definition in the source file. The compiler will parse that and store the information in some internal representation within the memory of the compiler process.
It is the compiler which produces the instructions for the CPU, so only the compiler needs to know the size. The produced program doesn't produce instructions (self modification is not possible in C++ language), so it doesn't need to know about type definitions.

Questions and Verifications on immutable [string] objects c++

I've been doing some reading on immutable strings in general and in c++, here, here, and I think I have a decent understanding of how things work. However I have built a few assumptions that I would just like to run by some people for verification. Some of the assumptions are more general than the title would suggest:
While a const string in c++ is the closest thing to an immutable string in STL, it is only locally immutable and therefore doesn't experience the benefit of being a smaller object. So it has all the trimmings of a standard string object but it can't access all of the member functions. This means that it doesn't create any optimization in the program over non-const? But rather just protects the object from modification? I understand that this is an important attribute but I'm simply looking to know what it means to use this
I'm assuming that an object's member functions exist only once in read-only memory, and how is probably implementation specific, so does a const object have a separate location in memory? Or are the member functions limited in another way? If there are only 'const string' objects and no non-const strings in a code base, does the compiler leave out the inaccessible functions?
I recall hearing that each string literal is stored only once in read-only memory in c++, however I don't find anything on this here. In other words, if I use some string literal multiple times in the same program, each instance references the same location in memory. I'm going to assume no, but would two string objects initialized by the same string literal point to the same string until one is modified?
I apologize if I have included too many disjunct thoughts in the same post, they are all related to me as string representation and just learning how to code better.
As far as I know, std::string cannot assume that the input string is a read-only constant string from your data segment. Therefore, point (3) does not apply. It will most likely allocate a buffer and copy the string in the buffer.
Note that C++ (like C) has a const qualifier for compilation time, it is a good idea to use it for two reasons: (a) it will help you find bugs, a statement such as a = 5; if a is declared const fails to compile; (b) the compile may be able to optimize the code more easily (it may otherwise not be able to figure out that the object is constant.)
However, C++ has a special cast to remove the const-ness of a variable. So our a variable can be cast and assigned a value as in const_cast<int&>(a) = 5;. An std::string can also get its const-ness removed. (Note that C does not have a special cast, but it offers the exact same behavior: * (int *) &a = 5)
Are all class members defined in the final binary?
No. std::string as most of the STL uses templates. Templates are compiled once per unit (your .o object files) and the link will reduce duplicates automatically. So if you look at the size of all the .o files and add them up, the final output will be a lot small.
That also means only the functions that are used in a unit are compiled and saved in the object file. Any other function "disappear". That being said, often function A calls function B, so B will be defined, even if you did not explicitly call it.
On the other hand, because these are templates, very often the functions get inlined. But that is a choice by the compiler, not the language or the STL (although you can use the inline keyword for fun; the compiler has the right to ignore it anyway).
Smaller objects... No, in C++ an object has a very specific size that cannot change. Otherwise the sizeof(something) would vary from place to place and C/C++ would go berserk!
Static strings that are saved in read-only data sections, however, can be optimized. If the linker/compiler are good enough, they will be able to merge the same string in a single location. These are just plan char * or wchar_t *, of course. The Microsoft compiler has been able to do that one for a while now.
Yet, the const on a string does not always force your string to be put in a read-only data section. That will generally depend on your command line option. C++ may have corrected that, but I think C still put everything in a read/write section unless you use the correct command line option. That's something you need to test to make sure (your compiler is likely to do it, but without testing you won't know.)
Finally, although std::string may not use it, C++ offers a quite interesting keyword called mutable. If you heard about it, you would know that a variable member can be marked as mutable and that means even const functions can modify that variable member. There are two main reason for using that keyword: (1) you are writing a multi-thread program and that class has to be multi-thread safe, in that case you mark the mutex as mutable, very practical; (2) you want to have a buffer used to cache a computed value which is costly, that buffer is only initialized when that value is requested to not waste time otherwise, that buffer is made mutable too.
Therefore the "immutable" concept is only really something that you can count on at a higher level. In practice, reality is often quite different. For example, an std::string c_str() function may reallocate the buffer to add the necessary '\0' terminator, yet that function is marked as being a const:
const CharT* c_str() const;
Actually, an implementation is free to allocate a completely different buffer, copy its existing data to that buffer and return that bare pointer. That means internally the std::string could be allocate many buffers to store large strings (instead of using realloc() which can be costly.)
Once thing, though... when you copy string A into string B (B = A;) the string data does not get copied. Instead A and B will share the same data buffer. Once you modify A or B, and only then, the data gets copied. This means calling a function which accepts a string by copy does not waste that much time:
int func(std::string a)
{
...
if(some_test)
{
// deep copy only happens here
a += "?";
}
}
std::string b;
func(b);
The characters of string b do not get copied at the time func() gets called. And if func() never modifies 'a', the string data remains the same all along. This is often referenced as a shallow copy or copy on write.

is it possible to use function pointers this way?

This is something that recently crossed my mind, quoting from wikipedia: "To initialize a function pointer, you must give it the address of a function in your program."
So, I can't make it point to an arbitrary memory address but what if i overwrite the memory at the address of the function with a piece of data the same size as before and than invoke it via pointer ? If such data corresponds to an actual function and the two functions have matching signatures the latter should be invoked instead of the first.
Is it theoretically possible ?
I apologize if this is impossible due to some very obvious reason that i should be aware of.
If you're writing something like a JIT, which generates native code on the fly, then yes you could do all of those things.
However, in order to generate native code you obviously need to know some implementation details of the system you're on, including how its function pointers work and what special measures need to be taken for executable code. For one example, on some systems after modifying memory containing code you need to flush the instruction cache before you can safely execute the new code. You can't do any of this portably using standard C or C++.
You might find when you come to overwrite the function, that you can only do it for functions that your program generated at runtime. Functions that are part of the running executable are liable to be marked write-protected by the OS.
The issue you may run into is the Data Execution Prevention. It tries to keep you from executing data as code or allowing code to be written to like data. You can turn it off on Windows. Some compilers/oses may also place code into const-like sections of memory that the OS/hardware protect. The standard says nothing about what should or should not work when you write an array of bytes to a memory location and then call a function that includes jmping to that location. It's all dependent on your hardware and your OS.
While the standard does not provide any guarantees as of what would happen if you make a function pointer that does not refer to a function, in real life and in your particular implementation and knowing the platform you may be able to do that with raw data.
I have seen example programs that created a char array with the appropriate binary code and have it execute by doing careful casting of pointers. So in practice, and in a non-portable way you can achieve that behavior.
It is possible, with caveats given in other answers. You definitely do not want to overwrite memory at some existing function's address with custom code, though. Not only is typically executable memory not writeable, but you have no guarantees as to how the compiler might have used that code. For all you know, the code may be shared by many functions that you think you're not modifying.
So, what you need to do is:
Allocate one or more memory pages from the system.
Write your custom machine code into them.
Mark the pages as non-writable and executable.
Run the code, and there's two ways of doing it:
Cast the address of the pages you got in #1 to a function pointer, and call the pointer.
Execute the code in another thread. You're passing the pointer to code directly to a system API or framework function that starts the thread.
Your question is confusingly worded.
You can reassign function pointers and you can assign them to null. Same with member pointers. Unless you declare them const, you can reassign them and yes the new function will be called instead. You can also assign them to null. The signatures must match exactly. Use std::function instead.
You cannot "overwrite the memory at the address of a function". You probably can indeed do it some way, but just do not. You're writing into your program code and are likely to screw it up badly.

Cost of using functions in fortran (or any other language)

Let say I have a array which is very big verybigvariable
And I have defined a function that does some operations like this
function myfunc(var) result(res)
real:: var(:,:,:),res
...
...
...
end function myfunc
My question is that when I call this function like this
myvar=myfunc(verybigvariable)
what happens? does it duplicate my variable so it holds 2X space in the ram during the execution of the function? If so how can I prevent this? (In a simple program, I know, I can define the function without any parameter and make it use existing variables, but If I am programming a module, it seems I have to include parameter to the definition)
The Fortran language standard does not specify how arguments are passed. Typically in the interest of efficiency the compiler will not make a copy but pass the address of the argument. There will be cases in which a Fortran compiler has to make a copy. E.g., the actual argument is a non-contiguous array but the procedure expects a contiguous argument. The compiler will have to fix the mismatch by making a copy that is contiguous to pass to the procedure. If the procedure modifies that argument, the values have to be copied back to the original argument.
In fortran it seems that parameters are passed by reference. This means that only the address of the variable is passed, and the function can then access the variable through that address.
So no, the array is not copied, only the address of the array is passed. The overhead for this will be either 32 bits for a 32-bit system, or 64 bits for a 64-bit system.
I have no experience with fortran, and this is only what I could figure out though a Google search, so if any Fortran programmers have any remarks, please feel free to edit/comment.

Compiler optimization problem

Most of the functions in <functional> use functors. If I write a struct like this:
struct Test
{
bool operator()
{
//Something
}
//No member variables
};
Is there a perf hit? Would an object of Test be created? Or can the compiler optimize the object away?
GCC at least can optimize the object creation and inline your functor, so you can expect performance as with hand-crafted loop. Of cource you must compile with -O2.
Yes, the compiler can optimize "object creation" (which is trivial in this case) out if it wants so. However if you really care you should compile your program and inspect the assembly code.
Even if the compiler was having a bad day and somehow couldn't figure out how to optimize this (it's very simple as optimizations go) - with no data members and no constructor the "performance hit" to "create an object" would be at most one instruction (plus maybe a couple more to copy the object, if the compiler also doesn't figure out how to inline the function call that uses the functor) to increment the stack pointer (since every object must have a unique address). "Creating objects" is cheap. What takes time is allocating memory, via new (because the OS has to be petitioned for the memory, and it has to search for a contiguous block that isn't being used by something else). Putting things on the stack is trivial.
There is no "use" of the structure, so as the code currently stands, it is still just a definition (and takes up no space).
If you create an object of type Test, it will take up non-zero space. If the compiler can deduce that nothing takes its address (or anything similar), it is free to optimize away the space usage.