#include <iostream> using namespace std; typedef int (*func)(int a, int b); int call_func(int a, int b) { return a + b; } void function(int a, int b, func f); int main () { function(5, 2, &call_func); system("pause"); } void function(int a, int b, func f) { int sum = (*f)(a, b); std::cout << "Sum = " << sum << std::endl; } 

typedef introduces a new name for the type, and I think examples of the typedef int int32 are clear to anyone. Well, what about typedef int (*func)(int a, int b); in this code, it should substitute int (int a, int b) f instead of func f , but substitutes int f (int a, int b), although I do not understand this, but also how he knows what to replace you need func, because it is an incomplete type or name. Description of typedef on the Internet ends with typedef int int32 or just with an example of structures and functions or some other complex types, but without explanation. I do not know what to think anymore, it was somehow easier with define.

  • 2
  • [@avp] [1], The service information is always at the end of the array and was there an error when I overwritten it and started the project in MSVC? In that code, it is in my two cells src [63] [17] src [63] [18], then you can write with thousand indices instead of 17 and 18, until there are errors in access rights. And when I tried to overwrite those two cells, the error was "This may be caused by damage to the heap and indicates an error in test.exe or in one of the DLLs loaded by it.". [1]: hashcode.ru/users/232/avp - mzarb
  • one
    @mzarb: (2) Technically this is indeed a 256 byte piece of memory available for use. The array in C "turns" into a pointer to the first element, and the address arithmetic is consistent with the array indexing: if float* p = new float[64] , then p + 2 points to the array element with index 2, that is, the 8th byte ( and not the 2nd). (3) yes, it is. (4) read my favorite related question . It is in English, but you plow through the text and enjoy it. - VladD
  • one
    @avp: formally, the record "past" the allocated memory is UB, the optimizer has the right to crash the program. For example, this is what Clang does: 1 , 2 , 3 . - VladD
  • one
    @VladD, IMHO it is obvious that there is no need to go where you go. I did not even think to focus on this. And if the program with such errors falls, then this is happiness . Worse, when doing something, and the results are only sometimes wrong. - avp

1 answer 1

typedef is not just a text substitution. It works as follows: if X is the name of a typedef type, the declaration of the variable is X x; works as if this place is the type description in typedef , where X replaced by x .

I.e

 typedef int (*func)(int a, int b); func f; 

works like

 int (* /*было func, стало*/ f )(int a, int b); 
  • one
    @mzarb: See. M * src means that *src is of type M , that is, float *src[16] , as you rightly wrote. Now, sizeof(M) is, of course, 16 * sizeof(float) = 64 . new M[sizeof(M)] creates an array and 64 pieces of M , that is, 64 * 16 floats. - VladD
  • one
    @mzarb: the author of the question highlights more elements than necessary (64, but only 16 are needed), and uses only the first 16 of them. (Check: ideone.com/E1mx7S ) - VladD
  • one
    @mzarb: It's simple. new float[16][64] allocates an array of 64 pieces float[16] , running in a row. This array is compatible with the pointer to the first element, that is, the pointer to float[16] . Our mat indeed such a pointer: float (*mat)[16] means that the type of *mat is float[16] , that is, mat itself is a pointer to float[16] . --- In order not to conduct all this type arithmetic in the mind, typedef was invented. - VladD 5:06
  • one
    @mzarb: (1) the compiler does not work with the textual representation. Example: if you have a function int s(int x, int y) { return x * y; } int s(int x, int y) { return x * y; } , and you call it: s(1 + 2, 3 + 4) , the compiler will not perform text substitution, and calculate 1 + 2 * 3 + 4 , it will behave as if there are brackets. See you The same thing happens with typedef. (2) float[64] is the type that the x variable would have had when declaring float x[64] . (3) again, no brackets, the compiler works with types, not with textual representations, it does not need brackets. (4) Why do you think 1028 stands out? - VladD
  • 2
    @mzarb, why did you decide that any entry past the allocated memory would cause an error? See what you get with writing to src [1030] and src [1024]. In fact, these are the same addresses as src [0] [1030] and src [63] [16]. As a result of the new call, 4096 bytes were allocated and the last really selected item is src [1023]. Next (obviously in your test) is not yet distributed memory. At its beginning (say 8 or 16 bytes), the function new will write some service information. Writing to src [1024] will spoil it, which will be found on the next new (or delete) (continued next - avp