A macro usage problem in VC a2w w2a

Source: Internet
Author: User

Here is a question about macros. I have used ATL's String Conversion macros, including w2a, which I don't quite understand at first. To use these macros, you must start with the function.

Use uses_conversion to initialize some local variables. Use it, but let's look at the macro definition. It has the following code:

// In the atlconv. h file

# Define uses_conversion \

Int _ convert ;\

Uint _ ACP = getacp (); _ ACP ;\

Lpcwstr _ lpw ;\?

Why do we use "int X;" for the lpcstr _ LPA; _ LPA? -- this is followed by the variable declaration?

Many people have encountered this confusing problem and later found that the answer is simple: Prohibit the warning information of the compiler (warning ). If there is a single line of code:

Int X;

If X has never been used, the compiler reports the error "unreferenced local variable: X", which means that the local variable X has not been referenced. If the warning information output is adjusted to the maximum

. To avoid annoying warnings, uses_conversion references declared variables.

Int X; // Declaration

X; // use this variable

In the era before C ++, Programmers sometimes use function parameters in C to avoid "unreferenced formal parameter" or other obscure compilation errors.

Void myfunc (int x, char y)

{

X;

Y;

......

}

Of course, the following code can be used to accomplish the same thing more effectively:

// Parameter X is not used

Void myfunc (INT/* x */)

{

......

} That is to say, the parameter is declared, but it cannot be named. Local variables cannot be used like this; it must be explicitly referenced. In this way, no commands are added to the Code. A maximum

Several bytes to the stack (null space reserved for X ). The clever compiler doesn't even worry about X's never been used. Although curiosity may want to know: If the compiler is powerful enough

Why do I complain about not using X? The answer is that demanding programmers (whose programming skills are related to their personal memory) use the compile warning to remind themselves to delete some of their generations.

Variable waste occurs when the Code occurs. This warning is useful in the C era. You must declare variables at the top of each function, so that you are far away from using their code.

Now let's look at another question: why do we need uses_conversion at the beginning? That is why macros such as w2a and CO still need another macro to declare their own variables; why not directly

Is this variable declared in w2a?

# Define w2a (x )\

Int _ convert ;\

...... Etc

Obviously, this cannot be done, because if you use w2a twice, you will get a replicated variable. So why don't we put the whole macro into the new range created by the curly arc?

# Define w2a (x) q {\

Int _ convert ;\

...... \

}

This solves the naming conflict, but cannot be encoded as follows:

Dosomething (w2a (pwstr ));

There is no way to return values from the code block, so w2a cannot be passed in function calls. So how about inline functions?

Inline lpcstr w2a (lpwstr W ){

Int_convert;

......

}

This solves the range problem-any variable required by w2a can be declared in this function within its own range, without the need for another macro. It also provides a way to return values,

This allows you to use w2a (x) in function calls and assignments ). However, this method is ineffective because w2a is more complicated than other macros.

No matter when Unicode conversion is performed, the string cannot be converted locally. A temporary string must be assigned to accommodate the converted bytes. Typically, assign a string by calling New:

Int Len = multibytetowidechar (...,?

Mystr, null, 0); // or length

Lpwstr P = new wchar [nlen]; // allocate memory

Multibytetowidechar (..., P, Len); // Conversion

Somecomfunction (p); // use

Delete [] P; // destroy

This code is not only annoying, but also inefficient. You must call multibytetowidechar twice (one is the length of the computation and the other is the actual conversion) and you have to allocate it from the heap.

P. This is very slow. Solve the first problem by allocating 2 * len bytes. Here the length Len is the length of the ASCII string-but what should we do with the second problem? If you want to see how a2w is expanded,

See:

// Simplified version

# Define a2w (s )\

_ Len = 2 * strlen (s );

Afxa2whelper (lpwstr) alloca (_ Len );

Afxa2whelper is an auxiliary function that calls multibytetowidechar. A2w uses 2 * Len to cleverly avoid calling multibytetowidechar twice. But a2w and others

To change the macro, we are smart: instead of calling the new operation to allocate a temporary string, we call alloca to allocate bytes in the stack, rather than in the heap. This is very fast, because the compiler has to do

Just add a stack pointer. Do not call a function or process memory blocks. It also avoids memory fragments and does not need to call the delete operation, because when the control leaves alloca, The called address

Memory is automatically released. This explains why a2w cannot be an inline function. If so, the temporary string created by alloca will be destroyed before the return, and you will delete

Method to terminate the call of somecomfunction (in this example.

A2w must call alloca from the same address called by alloca -- so a2w must be a macro rather than a function. Therefore, it needs another macro users_conversion to declare

_ Len and other variables used (I omitted them for simplicity ). When you think about it, the whole process tells us that if we want to write a set of macros like a2w, the allocation of memory from the stack will be reduced.

A lot of unnecessary troubles.

In addition, you can call alloca whenever you want to quickly obtain the temporary memory. The following code is common:

Char * P = new char [Len];

Dosomething (P );

Delete [] P;

It is more efficient to replace the following code:

Char * P = (char *) alloca (LEN );

Dosomething (P );

// You do not need to call Delete P!

Of course, if there are not so many in the stack, you will see a nasty message box. This method has some limitations. For more information, see the documentation. Experience tells me

No matter when you find strange things in MFC, ATL, or somewhere else, you 'd better drill into it and you may find useful things.

Me: Some people say that w2a may cause problems when it is frequently called. If the alloca memory is controlled by the system and does not need to be deleted, the problem should be that the call is too frequent.

The stack memory is exhausted, so the insurance method is to use {} to package w2a During frequent calls, so that resources will be automatically released upon exit.
For (INT I = 1; I <10000; I ++)
{
{
W2a (...)
}
}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.