Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Start switching System.Native from C++ to C#25032

Merged
jkotas merged 9 commits intodotnet:masterfrom
luhenry:switch-to-c
Nov 16, 2017
Merged

Start switching System.Native from C++ to C#25032
jkotas merged 9 commits intodotnet:masterfrom
luhenry:switch-to-c

Conversation

@luhenry
Copy link
Copy Markdown

@luhenry luhenry commented Nov 3, 2017

Motivation: Sharing code between .NET Core and Mono.

@SunnyWar
Copy link
Copy Markdown
Contributor

SunnyWar commented Nov 3, 2017

@luhenry perhaps a few words in the description describing the motivation behind this work?

Copy link
Copy Markdown
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM otherwise. Thanks!

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);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to keep memcpy_s here? It is mandated by SDL rules...

Comment thread src/Native/Unix/Common/pal_compiler.h Outdated

// These defines are temporary until all files have been migrated from C++ to C
#ifdef __cplusplus
#define BEGIN_DECLS extern "C" {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) ||
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep multiply_s here? Another SDL requirement.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Multiple places)

PAL_ESHUTDOWN = 0x1006C, // Socket shutdown.
PAL_EHOSTDOWN = 0x10070, // Host is down.
PAL_ENODATA = 0x10071, // No data available.
ERROR_E2BIG = 0x10001, // Argument list too long.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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));
Copy link
Copy Markdown
Member

@jkotas jkotas Nov 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@jkotas
Copy link
Copy Markdown
Member

jkotas commented Nov 3, 2017

Linux builds fail with 2:27: error: implicit declaration of function 'strerror_r' is invalid in C99 [

Copy link
Copy Markdown
Member

@stephentoub stephentoub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than Jan's comments, LGTM.

@luhenry luhenry force-pushed the switch-to-c branch 3 times, most recently from 64a2bb1 to 7ca77f5 Compare November 6, 2017 17:13
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")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@luhenry luhenry force-pushed the switch-to-c branch 2 times, most recently from 4f8f60a to 09854f4 Compare November 9, 2017 18:01
@jkotas
Copy link
Copy Markdown
Member

jkotas commented Nov 9, 2017

Linux build failing with errors like:

/mnt/j/workspace/dotnet_corefx/master/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_false_prtest/src/Native/Unix/System.Native/pal_io.c:66:1: error: _Static_assert is a C11-specific feature [-Werror,-Wc11-extensions]
static_assert(PAL_S_ISGID == S_ISGID, "");
^
/usr/include/assert.h:119:24: note: expanded from macro 'static_assert'
# define static_assert _Static_assert

Comment thread src/Native/Unix/Common/pal_safecrt.h Outdated

// 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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these rather return bool ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool doesn't exist with C99, so the usual replacement is int8_t. Maybe we could add a typedef int8_t bool.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#include <stdbool.h> ?

@luhenry luhenry force-pushed the switch-to-c branch 5 times, most recently from 7d170bd to b79c347 Compare November 14, 2017 15:25
@luhenry
Copy link
Copy Markdown
Author

luhenry commented Nov 14, 2017

@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

Copy link
Copy Markdown
Member

@jkotas jkotas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - just a few nits

Comment thread src/Native/Unix/Common/pal_safecrt.h Outdated
assert(src != NULL);
assert(sizeInBytes >= count);
#ifdef __cplusplus
assert( // should be using memmove if this fails
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need these sort of ifdefs? I would expect the C version should work for C++ fine too. (Multiple places.)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C++ warns of using "old style" casting (with (const char*)), while static_cast produces no warning.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread src/Native/Unix/System.Native/pal_io.c Outdated
#define lstat_ lstat
#endif

#ifdef static_assert
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should be define the static_assert in the common header if it is not defined? It would be better than ifdefing each use.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)),
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unchecked should not be necessary

/// Specifies the states of a Transmission Control Protocol (TCP) connection.
/// </summary>
public enum TcpState
public enum TcpState : int
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really necessary. This is a public type, so nobody can change it anyway.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disable it globally? Seems like a pretty useless warning for the kind of code that System.Native is.

@luhenry
Copy link
Copy Markdown
Author

luhenry commented Nov 16, 2017

@jkotas @stephentoub I updated according to latest review.

@jkotas jkotas merged commit 6a9f579 into dotnet:master Nov 16, 2017
@jkotas
Copy link
Copy Markdown
Member

jkotas commented Nov 16, 2017

@luhenry Thank you!

@tmds
Copy link
Copy Markdown
Member

tmds commented Nov 16, 2017

@luhenry, just to understand, why doesn't mono use c++?

@luhenry
Copy link
Copy Markdown
Author

luhenry commented Nov 16, 2017

@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.

@karelz karelz added this to the 2.1.0 milestone Nov 18, 2017
@ghost
Copy link
Copy Markdown

ghost commented Mar 3, 2018

@luhenry, for the remaining C++ files in this repository, is there a plan to convert them as well?

picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* 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
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants