# CodeGuru Technical FAQs > CodeGuru Individual FAQs >  ATL String: What's wrong with the USES_CONVERSION macros? How to avoid using them?

## Siddhartha

*Q:* ATL String: What's wrong with the USES_CONVERSION macros? How to avoid using them?

*A:* The simplest way (in ATL 3.0) to convert a _Wide Character String_ to an _ANSI String_ is by using OLE2A or W2A, and their equivalent _Macros_. _Simplest, but not the safest!_



```
BSTR bstrMyBeaster = SysAllocString (L"Tring, Tring!");
WCHAR* pwszMyWCharString = L"Tring, Tring!";
 
USES_CONVERSION;
LPSTR pszCharStringFromBSTR = OLE2A (bstrMyBeaster);
LPSTR pszCharStringFromLPWSTR = W2A (pwszMyWCharString);
// ...
SysFreeString (bstrMyBeaster);
```

 
*Q:* If it is simple and if it works, then, what's wrong in using it?

*A:* Macros such as OLE2A, W2A and the likes cause _Stack Overflows_ when used in _loops_.The reason: 

They allocate memory using _alloca _alloca allocates memory on the _Function Stack_. This memory is released ("_popped_") only on function exit.   
So, a _loop that loops too often_ and _converts_ strings can result in a situation where the stack has no space left to offer.

This situation causes a *Stack Overflow Exception*.

Sample of a Prospective Stack Overflow Exception causing Function:



```
int StackGuzzler (void)
{
  WCHAR* pwszTest = SOME_WCHAR_STRING;

  for (int nCounter = 0; nCounter < SOME_MAX_COUNT; nCounter++)
  {
	USES_CONVERSION;
	LPSTR pszCharVersion = W2A (pwszTest); // Allocated on stack
  }

  return 1;
} // Stack Memory is cleared i.e. "popped" here - this is sometimes too late!

```



*Q:* How do we overcome this Stack Overflow problem?

*A:* By not using the macros. 

By simply delegating the string conversion to another function - one that returns the ANSI String (i.e. 'char*' or 'LPSTR' allocated on the _heap_/_free store_). 

If you are using ATL 7.0, you have the option to use a set of Conversion Classes that are better suited. Take a look at the next question for further information.

Function that _safely_ converts a BSTR to LPSTR:



```
char* ConvertBSTRToLPSTR (BSTR bstrIn)
{
  LPSTR pszOut = NULL;
  if (bstrIn != NULL)
  {
	int nInputStrLen = SysStringLen (bstrIn);

	// Double NULL Termination
	int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, NULL, 0, 0, 0) + 2; 
	pszOut = new char [nOutputStrLen];

	if (pszOut)
	{
	  memset (pszOut, 0x00, sizeof (char)*nOutputStrLen);
	  WideCharToMultiByte (CP_ACP, 0, bstrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
	}
  }
  return pszOut;
}
```

Function that _safely_ converts a 'WCHAR' String to 'LPSTR':



```
char* ConvertLPWSTRToLPSTR (LPWSTR lpwszStrIn)
{
  LPSTR pszOut = NULL;
  if (lpwszStrIn != NULL)
  {
	int nInputStrLen = wcslen (lpwszStrIn);

	// Double NULL Termination
	int nOutputStrLen = WideCharToMultiByte (CP_ACP, 0, lpwszStrIn, nInputStrLen, NULL, 0, 0, 0) + 2;
	pszOut = new char [nOutputStrLen];

	if (pszOut)
	{
	  memset (pszOut, 0x00, nOutputStrLen);
	  WideCharToMultiByte(CP_ACP, 0, lpwszStrIn, nInputStrLen, pszOut, nOutputStrLen, 0, 0);
	}
  }
  return pszOut;
}
```

Using them:



```
LPWSTR pwszMyWideCharString = L"Tring, Tring!";
LPSTR pszSimpleCharStringFromLPWSTR = ConvertLPWSTRToLPSTR(pwszMyWideCharString);

// .. use the string

delete [] pszSimpleCharStringFromLPWSTR;
SysFreeString (bstrMyBeaster);
```

and

```
BSTR bstrMyBeaster = SysAllocString (L"Tring, Tring!");
LPSTR pszSimpleCharStringFromBSTR = ConvertBSTRToLPSTR(bstrMyBeaster);

// ... use the string

delete [] pszSimpleCharStringFromBSTR;
SysFreeString (bstrMyBeaster);
```

The two methods above _totally erase the possibility of causing a Stack Overflow_ whilst converting Wide-Character Strings.


*Q:* Does this issue persist with ATL 7.0?

*A:* Fortunately, *no* - as you now have the option to not use these macros. Changes with ATL 7.0: 

ATL 7.0 claims to resolve the issue of accumulating memory allocation per loop-cycle.ATL 7.0 does not require USES_CONVERSION macros.ATL 7.0 provides _conversion (template) classes_, and not macros. 


```
 
CW2T pszString (L"Tring Tring"); 
  
// Use it as a LPCTSTR 
std::cout << pszString;
```

For more information on how to convert strings using ATL 7.0, visit: ATL 7.0 String Conversion Classes and Macros.

----------

