Tacti Tacoz
Tacti Tacoz
CC#
Created by Tacti Tacoz on 11/13/2024 in #help
Ignore strong names
I was using way too long hunting down the reason for a CS0012, I had the assumption that a non strong named assembly reference can bind to a strong named assembly reference just not the other way around which I thought was logical. (btw an error message with more info could have been useful) But yeah, no some debugging and browsing of roslyn code base eventually made me notice that if either is strong named both must be. This means nuget packages that come shipped strong named (like newtonsoft.json) will break comparability with older libraries, potentially, and including in my case, some you don't have control over. Older versions, in most cases, works just fine in my use case. So the question is, does MSBuild or the <PackageReference> tag it self have a way to either: 1. Ignore the strong name binding rule and don't emit it in metadata (but leaving potential build output with strong named assemblies that can be patched if nessesary) or, 2. preferably, strip the strong name binding entirely before building. Or am I really forced to reupload a strong name stripped version my self? I'm sure someone else has found this annoying, or am I missing something here? I noticed some library authors have decided to offer a strong named assembly separately, so some people seems to have gotten the message. I am not mentioning at runtime since that is disabled in the runtime by default? atleast by some configurations, regardless it can be easily hacked at runtime by resolve events.
3 replies
CC#
Created by Tacti Tacoz on 3/7/2024 in #help
Redirecting the native standard output stream
I need to call into native code the problem is that it writes some of it's output using stdout. Is it possible to redirect stdout to a file (or one of the virtual file streams types) and then direct it back to the default console output afterwards? System.Console.SetOut doesn't effect native code at all and only changes logging done via System.Console.WriteLine (and co) I can find C++ examples to do so, but they do not seem to use any easily pinvokeable library like the method I tried below. Creating my own native dll for this seems a bit overkill. https://learn.microsoft.com/en-us/windows/console/setstdhandle Seems to be related but has no effect, even though it's returning non zero like the documentation says. I would like to clarify this is native code called within the same process not managed code starting a native process. Ways to do that is well documented.
1 replies
CC#
Created by Tacti Tacoz on 2/19/2024 in #help
✅ Circular References
No description
56 replies
CC#
Created by Tacti Tacoz on 1/2/2024 in #help
collection expression on Span<T>
Just a quick question, wasn't something like
void TestMethod(Span<int> span);

TestMethod([1]);

//Suppose to emit something like:
var _arg = 1;
TestMethod(new(&_arg, 1));
//Or
Span<int> span = stackalloc int[1];
span[0] = 1;
TestMethod(span);
void TestMethod(Span<int> span);

TestMethod([1]);

//Suppose to emit something like:
var _arg = 1;
TestMethod(new(&_arg, 1));
//Or
Span<int> span = stackalloc int[1];
span[0] = 1;
TestMethod(span);
Did they skip anti allocation improvements like this initially? right now it just allocates an array.
9 replies
CC#
Created by Tacti Tacoz on 11/15/2023 in #help
Extension Types Delay?
It seems the language design team has decided to delay the implicit and explicit extension type (formally extentions and roles) feature for C# 12. Personally the feature I was the most hyped for. Are anyone aware of an official reason as to why it was delayed? Google seems to be letting me down here.
23 replies
CC#
Created by Tacti Tacoz on 4/19/2023 in #help
✅ What is the deal with default jit optimizations
According to my memory debugger
interface ITest1
{
}
interface ITest2 { }

struct Test1 : ITest1
{
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static bool test1<T>(ref T value)
{
return value is ITest1;
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static bool test2<T>(ref T value)
{
return value is ITest2;
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object Test<T>(ref T value)
{
bool flag = true;
int x = 0;
int y = 0;
while (flag)
{
if (test1(ref value))
x++;
if (test2(ref value))
y++;
}
return null;
}
interface ITest1
{
}
interface ITest2 { }

struct Test1 : ITest1
{
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static bool test1<T>(ref T value)
{
return value is ITest1;
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static bool test2<T>(ref T value)
{
return value is ITest2;
}
[System.Runtime.CompilerServices.MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static object Test<T>(ref T value)
{
bool flag = true;
int x = 0;
int y = 0;
while (flag)
{
if (test1(ref value))
x++;
if (test2(ref value))
y++;
}
return null;
}
The generic value given to test1 and test2 gets boxed at every iteration. Now in a debug senario this isn't surprising given that the emited il for this is indeed boxing. But I thought boxing like this are suppose to be optimized out by default in a release build. To make this code get optimized like it should be "AggresiveOptimization" flag has to be manuelly used. My project settings are standard .net 7 settings. Unless I'm missing something this seem rarther odd. Infact the implementation of hot and common code paths like GenericEqualityComparer depend on semilare optimization to happen. Obviously that is getting optimized otherwise simple collection lookups would blow the GC up on a regular basis. Having optimizations disabled by default is surely not the intended behavior here? Surely my memory debugger are making some pretty heavy assumptions without actuelly analyzing memory allocations correctly right? Thanks in advance for any insight you guys can give.
31 replies
CC#
Created by Tacti Tacoz on 9/21/2022 in #help
readonly struct and readonly struct instance members (optimization?)
Hey you beautiful people. Recently I experimented with readonly struct's and readonly struct instance members (as one does) However the compiler for this doesn't quite act like I expected it to. Consider something like this for instance:
public readonly struct TestStruct
{
public static TestStruct New()
=> new() { _array = new float[SomeEnumLenght] };
private readonly float[] _array;
public readonly float this[SomeEnum key] // IMO adding "readonly" to instance members when the hole struct is readonly is a bit silly, but just adding it here incase that makes a difference?
{
get => _array[(int)key];
set => _array[(int)key] = value;
}
}

static class Program
{
static void Main()
{
var test = new TestStruct();
_=test[0];
}
}
public readonly struct TestStruct
{
public static TestStruct New()
=> new() { _array = new float[SomeEnumLenght] };
private readonly float[] _array;
public readonly float this[SomeEnum key] // IMO adding "readonly" to instance members when the hole struct is readonly is a bit silly, but just adding it here incase that makes a difference?
{
get => _array[(int)key];
set => _array[(int)key] = value;
}
}

static class Program
{
static void Main()
{
var test = new TestStruct();
_=test[0];
}
}
I would expect the il for the "_=test[0];" line to be something roughly like this: ldloc.0 ldc.i4.0 call TestStruct::get_item(SomeEnum key) pop But from my testing, it seems the compiler does the less efficient route (the route of which I thought readonly struct was designed to prevent) of: ldloca.s 0 ldc.i4.0 call TestStruct::get_item(SomeEnum key) pop aka it passes a pointer of the "test" local instead of by value to the get_item call (which for my understanding passing by value would be the expected behaviour here) I'm using a custom compiler atm (I'm gonna try this with VS too) that are using the official roslyn codeanalysis nuget package
2 replies
CC#
Created by Tacti Tacoz on 8/23/2022 in #help
Change Visual Studio suggetions with custom analysers
Hiya.. ohh discords new "forum" channels are super useful for this huh?. anyway. So I managed to implement a C# proposal https://github.com/dotnet/csharplang/discussions/6394 (that is I implemented it using an analyser extension) for my own use. there is 1 problem though I can't seem to figure out how I tell visual studios "suggestions" feature (where when you start typing suggestions for member names, type names, etc show up.) what members and types it should and shouldn't suggest. I would have thought that is a common use of analysers and that the extension and or analyser api has some kind of build in method to do it, or atleast I hope(ed). Let me know what I'm missing. Thanks everyone.
30 replies