7

The Windows documentation for WSAStringToAddress states:

INT WSAAPI WSAStringToAddress(
  _In_     LPTSTR             AddressString,
  _In_     INT                AddressFamily,
  _In_opt_ LPWSAPROTOCOL_INFO lpProtocolInfo,
  _Out_    LPSOCKADDR         lpAddress,
  _Inout_  LPINT              lpAddressLength
);

AddressString an _In_ parameter, and not an _Inout_ parameter. Its not clear to me why the API takes a non-const pointer, and its causing a compile failure because I have a const char*.

My first question is, why does WSAStringToAddress take a non-const pointer?

My second question is, is it safe to cast the const-ness away? Will WSAStringToAddress modify the char* argument?


Here's more of the back story... I'm trying to use WSAStringToAddress in an inet_addr replacement due to deprecated warnings under contemporary versions of Visual Studio.

Here's the same problem detailed in a question with an answer provided by Petar Korponaić. Korponaić experienced the same problem. Its the reason for the extra copy:

int inet_pton(int af, const char *src, void *dst)
{
  struct sockaddr_storage ss;
  int size = sizeof(ss);
  char src_copy[INET6_ADDRSTRLEN+1];

  ZeroMemory(&ss, sizeof(ss));
  /* stupid non-const API */
  strncpy (src_copy, src, INET6_ADDRSTRLEN+1);
  src_copy[INET6_ADDRSTRLEN] = 0;

  if (WSAStringToAddress(src_copy, af, NULL, (struct sockaddr *)&ss, &size) == 0)
  ...
}
jww
  • 97,681
  • 90
  • 411
  • 885
  • 2
    There are some Windows apis - and this may or may not be one of them - that modify strings in place - for example to add a terminating zero to use a string fragment with an api that expects a zero terminated string, and then restoring the overwritten character. If you just cast away the constness you can introduce race conditions or an exception if the source string is a literal stored in read only memory. – Chris Becke Oct 10 '16 at 11:24
  • 1
    @ChrisBecke: Those parameters are attributed using one of the `_Inout_` SAL annotations (like the *lpCommandLine* parameter in [CreateProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425.aspx)). In this case, however, there is an `_In_` annotation. Since SAL annotations are evaluated both at the call site as well as the implementation, I would assume, that *AddressString* can be a constant. I wouldn't think that the deployed *Ws2_32.dll* binary compiles with warnings (or has certain SAL warnings disabled), although I haven't reverse engineered the code. – IInspectable Oct 10 '16 at 13:32

1 Answers1

0
  1. The Windows is a C API, thus C strings defined as "Some string" are not constant. C++ changes that by making them constant.
  2. Yes it is perfectly safe to cast away the constness using const_cast<LPTSTR>("my string").
Arush Agarampur
  • 1,340
  • 7
  • 20
  • 1
    You can only cast away const if the object is non-const. An example of undefined behavior is, `const char site[] = "www.google.com";` followed by `WSAStringToAddress(site, ...)`. The const cannot be cast away because the object is const. Also see [Is it safe to remove const via const_cast and invoke a non-const function that does not modify the resulting object?](https://stackoverflow.com/q/29883327/608639) – jww Sep 12 '19 at 02:42