Start switching System.Native from C++ to C#25032
Conversation
|
@luhenry perhaps a few words in the description describing the motivation behind this work? |
| if ((vflag & INP_IPV4) == INP_IPV4) | ||
| { | ||
| memcpy_s(iepi->AddressBytes, sizeof(IPEndPointInfo::AddressBytes), &in_pcb.inp_laddr.s_addr, 4); | ||
| memcpy(iepi->AddressBytes, &in_pcb.inp_laddr.s_addr, 4); |
There was a problem hiding this comment.
Would it be possible to keep memcpy_s here? It is mandated by SDL rules...
|
|
||
| // These defines are temporary until all files have been migrated from C++ to C | ||
| #ifdef __cplusplus | ||
| #define BEGIN_DECLS extern "C" { |
There was a problem hiding this comment.
Nit: I am wondering whether it would be better to use EXTERN_C macro. It is the more standard way to deal with this problem - in the codebases that I live in at least.
| { | ||
| delete[] buffer; | ||
| size_t tmpEstimatedSize; | ||
| if (!multiply_s(estimatedSize, static_cast<size_t>(2), &tmpEstimatedSize) || |
There was a problem hiding this comment.
Can we keep multiply_s here? Another SDL requirement.
| PAL_ESHUTDOWN = 0x1006C, // Socket shutdown. | ||
| PAL_EHOSTDOWN = 0x10070, // Host is down. | ||
| PAL_ENODATA = 0x10071, // No data available. | ||
| ERROR_E2BIG = 0x10001, // Argument list too long. |
There was a problem hiding this comment.
Nit: Maybe this should Error_E2BIG to follow the <enum name>_<field name> convention.
| if (err != 0) | ||
| { | ||
| return SystemNative_ConvertErrorPlatformToPal(errno); | ||
| return static_cast<Error>(SystemNative_ConvertErrorPlatformToPal(errno)); |
There was a problem hiding this comment.
These static_cast<Error> casts seem to be pretty frequent. Would it make sense to have ConvertErrorPlatformToPal local non-exporter variant (without the SystemNative_ prefix) that just returns Error?
There was a problem hiding this comment.
They will all go away as soon as the transition is done, as we won't be able to return Error to managed anymore, and just int32_t
|
Linux builds fail with |
stephentoub
left a comment
There was a problem hiding this comment.
Other than Jan's comments, LGTM.
64a2bb1 to
7ca77f5
Compare
| set(CMAKE_INCLUDE_CURRENT_DIR ON) | ||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") | ||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") | ||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") |
There was a problem hiding this comment.
I guess this can be removed now too. There are also a few more CXX variables which are used and need replacement too:
- CMAKE_CXX_COMPILER_VERSION
- CMAKE_CXX_FLAGS_DEBUG
- CLR_SANITIZE_CXX_FLAGS
4f8f60a to
09854f4
Compare
|
Linux build failing with errors like: |
|
|
||
| // Multiplies a and b into result. | ||
| // Returns true if safe, false if overflows. | ||
| inline static int8_t multiply_s(size_t a, size_t b, size_t* result) |
There was a problem hiding this comment.
Should these rather return bool ?
There was a problem hiding this comment.
bool doesn't exist with C99, so the usual replacement is int8_t. Maybe we could add a typedef int8_t bool.
7d170bd to
b79c347
Compare
|
@jkotas @stephentoub I updated the PR and it looks much greener now (still waiting for OSX). Could you please review again, so once we have the result for OSX we can get it merged? Thank you |
| assert(src != NULL); | ||
| assert(sizeInBytes >= count); | ||
| #ifdef __cplusplus | ||
| assert( // should be using memmove if this fails |
There was a problem hiding this comment.
Do we need these sort of ifdefs? I would expect the C version should work for C++ fine too. (Multiple places.)
There was a problem hiding this comment.
C++ warns of using "old style" casting (with (const char*)), while static_cast produces no warning.
There was a problem hiding this comment.
Disable the warning instead? Everything will get converted to the old style casts eventually, so we are not getting anything for being warned about using them.
| #define lstat_ lstat | ||
| #endif | ||
|
|
||
| #ifdef static_assert |
There was a problem hiding this comment.
If there is no standard way to do static_assert in C, can we define our own?
E.g. this is the classic definition used by Windows SDK that should work in C too:
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
There was a problem hiding this comment.
With newer Clang and GCC, static_assert is defined so the only case where we wouldn't compile these static asserts would be if you compile with an older version of Clang or GCC that do not support those.
There was a problem hiding this comment.
So should be define the static_assert in the common header if it is not defined? It would be better than ifdefing each use.
There was a problem hiding this comment.
15e76fb defines c_static_assert which fixes your comment. It forces us to define -Wno-typedef-redefinition, which might be quite detrimental. IMO since static_assert is not defined only on older compilers, just gating for its presence brings the best tradeoff.
| rawAddress, | ||
| unchecked((uint)addressBuffer.Length), | ||
| addr.AddressFamily == AddressFamily.InterNetworkV6, | ||
| unchecked((byte)(addr.AddressFamily == AddressFamily.InterNetworkV6 ? 1 : 0)), |
There was a problem hiding this comment.
Unchecked should not be necessary
| /// Specifies the states of a Transmission Control Protocol (TCP) connection. | ||
| /// </summary> | ||
| public enum TcpState | ||
| public enum TcpState : int |
There was a problem hiding this comment.
Not really necessary. This is a public type, so nobody can change it anyway.
There was a problem hiding this comment.
Shouldn't we make sure of the size, so we map properly the structure MibTcpRow? It uses a TcpState field, and having a different field size between managed and native would produce hard to debug bugs.
There was a problem hiding this comment.
The default size of enum in C# is always int. It is not hurting anything to add : int explicitly, but it is not obvious from looking at it why it is there.
| install (TARGETS System.Native-Static DESTINATION .) | ||
|
|
||
| # We have to cast struct to uint8_t and back | ||
| set_source_files_properties(pal_networkstatistics.c PROPERTIES COMPILE_FLAGS -Wno-cast-align) |
There was a problem hiding this comment.
Disable it globally? Seems like a pretty useless warning for the kind of code that System.Native is.
|
@jkotas @stephentoub I updated according to latest review. |
|
@luhenry Thank you! |
|
@luhenry, just to understand, why doesn't mono use c++? |
|
@tmds one of Mono's strength resides on its ease to embed into other projects. Switching to C++ would make it harder for multiple technical reasons, with the main one being the C++ runtime, as long as we didn't figure out a story for that, we will not be able to do the switch. Also, C is available on much more platforms than C++ (let alone C++11), and Mono needs to be able to go to all these places where a modern C++ compiler might not have gone yet. |
|
@luhenry, for the remaining C++ files in this repository, is there a plan to convert them as well? |
* Move System.Native/pal_maphardwaretype.cpp to C * Switch C compiler from C11 to C99 * Move System.Native/pal_errno.cpp to C * Move System.Native/pal_tcpstate.cpp to C * Move System.Native/pal_networkstatistics.cpp to C * Move System.Native/pal_memory.cpp to C * Move System.Native/pal_io.cpp to C * Move System.Native/pal_networking.cpp to C * Define c_static_assert for compiler that don't support static_assert Commit migrated from dotnet/corefx@6a9f579
Motivation: Sharing code between .NET Core and Mono.