dotnet/BenchmarkDotNet · error · NotSupportedException

Default BenchmarkActionFactory only supports void* return, n

Error message

Default BenchmarkActionFactory only supports void* return, not T*

What it means

The default InProcess NoEmit BenchmarkActionFactory supports void* returns for unsafe benchmarks but cannot marshal typed pointers T*; it throws NotSupportedException for them.

Source

Thrown at src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory.cs:126

            unrollFactor);
    }

    private static void PrepareInstanceAndResultType(object instance, MethodInfo targetMethod, out object? resultInstance, out Type resultType)
    {
        resultInstance = targetMethod.IsStatic ? null : instance;
        resultType = targetMethod.ReturnType;

        if (resultType == typeof(void))
        {
            // DONTTOUCH: async should be checked for target method
            // as fallbackIdleSignature used for result type detection only.
            bool isUsingAsyncKeyword = targetMethod?.HasAttribute<AsyncStateMachineAttribute>() ?? false;
            if (isUsingAsyncKeyword)
                throw new NotSupportedException("Async void is not supported by design.");
        }
        else if (resultType.IsPointer && resultType != typeof(void*))
        {
            throw new NotSupportedException($"Default {nameof(BenchmarkActionFactory)} only supports void* return, not T*");
        }
    }

    /// <summary>Helper to enforce .ctor signature.</summary>
    private static BenchmarkActionBase Create(Type actionType, object? instance, MethodInfo method, int unrollFactor) =>
        (BenchmarkActionBase)Activator.CreateInstance(actionType, instance, method, unrollFactor)!;

    private static readonly MethodInfo FallbackSignature = new Action(BenchmarkActionBase.OverheadStatic).GetMethodInfo();

    public static IBenchmarkAction CreateWorkload(IBenchmarkActionFactory? factory, Descriptor descriptor, object instance, int unrollFactor, bool consumeTasksSynchronously = false) =>
        CreateCore(factory, instance, descriptor.WorkloadMethod, unrollFactor, consumeTasksSynchronously);

    public static IBenchmarkAction CreateOverhead(IBenchmarkActionFactory? factory, Descriptor descriptor, object instance, int unrollFactor) =>
        CreateCore(factory, instance, FallbackSignature, unrollFactor);

    public static IBenchmarkAction CreateGlobalSetup(IBenchmarkActionFactory? factory, Descriptor descriptor, object instance) =>
        CreateCore(factory, instance, descriptor.GlobalSetupMethod ?? FallbackSignature, 1);

View on GitHub (pinned to b515068b61)

Solutions

  1. Return void* from the unsafe benchmark method, or change the return type to a supported managed type.
  2. If you need the pointer value, return IntPtr or nint instead of a typed pointer.
  3. Provide a custom BenchmarkActionFactory to handle T* returns.

When it happens

Trigger: Thrown at src/BenchmarkDotNet/Toolchains/InProcess/NoEmit/BenchmarkActionFactory.cs:126 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of dotnet/BenchmarkDotNet@b515068b61 (2026-08-13). Data as JSON: /api/errors/d0409fe301a41b8c. Report an issue: GitHub.