15 ms·
Span<T> in C#
- runesoerensen 9y agoSpan<T> was recently added to C# 7.2 https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-to-c-7-2-and-span/ https://blogs.msdn.microsoft.com/dotnet/2017/11/15/welcome-t..., and the early proposal was discussed a bit on HN last year: https://news.ycombinator.com/item?id=12713186 https://news.ycombinator.com/item?id=12713186 Also this blog post has more examples and benchmarks for people interested: http://adamsitnik.com/Span/ http://adamsitnik.com/Span/
- twotwotwo 9y agoC# was mostly irrelevant to me a long time when Microsoft's implementation was closed, but there are some neat things about it. They've done a lot of interesting stuff in the language since it first came out, including pragmatic sugar-y stuff like type inference (`var`), async/await, and recently some moves towards more functional-style pattern matching though they're not totally there yet (https://www.kenneth-truyers.net/2016/01/20/new-features-in-c-sharp-7/ https://www.kenneth-truyers.net/2016/01/20/new-features-in-c... discusses proposals, some of which didn't make C# 7). Interfaces and value types also seemed like important things to have early, and there's some other handy looking stuff like the SustainedLowLatency GC mode (defer full-heap compactions as long as it can). Can be tempting to think of it as a Java clone because of its early history and the shared general category (OO-focused GC'd imperative statically typed language whose first major impl was bytecode/VM-based), but there's signs of more to it than that.
- eighthnate 9y agoC# is a more polished and "prettier" Java. It has done well with it's incorporation of functional programming, generics, dynamic programming and syntactic sugar in the last few releases. Too bad it's pretty much confined to the windows ecosystem.
- jimmaswell 9y agoIt's not confined to the Windows ecosystem, aside from Mono there's now the officially supported cross-platform .NET Core.
- cat_phat 9y agoIt's definitely not confined to the windows ecosystem. I develop C# on OSX via Jetbrain's Project Rider and run the developed code on anything from linux to docker instances.
- megaman22 9y agoIn some alternate reality, progress on the Java language doesn't get lost in the shuffle in the death of Sun after 1.6 was released. Those five years of relative stasis hurt, especially where C# was making such strides. I took the AP CS test in high school with Java 6, and four years later, the jobs I was looking at after college were still Java 6. The ones where companies weren't still on Java 5, or even more archaic releases.
- Coincoin 9y ago> Too bad it's pretty much confined to the windows ecosystem. We released games written in C# for iOS, Android, Windows Phone, Windows PC and Linux servers.
- mythz 9y agoOur server library and framework software suite and Apps have been running cross-platform for several years and with the support of .NET Core 2.0 they now run fast and flawlessly on Linux which is a very popular deployment target for our Customers, in fact all our .NET Core Live Demos were developed on Windows and deployed to and running on Linux: - https://github.com/NetCoreApps/LiveDemos - https://github.com/NetCoreWebApps/LiveDemos Each project can also be opened and developed on Linux or Mac with VS Code or Rider. Xamarin's solutions has been making C# a popular language for developing native high-performance iOS/Android Apps for several years and the stigma of C# server apps being confined to Windows should be eradicated with the advent of .NET Core.
- pwdisswordfish 9y ago
- jmkni 9y agoI feel as though, with C#, Microsoft's brilliance was to get a number of very clever people in a room together (Anders Hejlsberg, Eric Lippert, etc). Somebody at Microsoft said to themselves, these guys are clearly brilliant, let's see what happens if we hire them all, task them with creating a new object oriented programming language, pay them a tonne of money, and see what happens. C# was the result, and it's awesome!
- seanmcdirmid 9y agoDon’t forget former Arhus professor Mads Tergesen, he’s been the lead C# designer for sometime now.
- na85 9y agoThe problem with C# for me is the fragmented ecosystem that's hard to navigate, coupled with dense and hard to find documentation that seems to be spread out over 14 different msdn domains and GitHub projects. CoreFX? CoreCLR? No idea what these are or what they're for. And don't get me started on the dumpster fire that is roslyn. I've tried no less than 10 times over the last few months to get "intellisense" working in emacs via roslyn and it has never worked. C#'s a cool language that I want to like but it's just so much work to get started with.
- lwansbrough 9y agoThere are many more names for things in C# than what you really need to be aware of as a C# developer. Want to write C# that targets Linux? Download the .NET Core SDK. Simple as. Everything else: .NET Standard, .NET Framework, are just names used by the .NET contributors to keep things straight in their head, but you honestly rarely deal with that stuff if you’re starting fresh with .NET Core. If you’re trying to write C# in emacs you’re doing it wrong. C# has probably the best tooling in the world if you embrace it.
- qdot76367 9y agoAgreed. I basically live in emacs, but for C#, I'm in VS 2017 community and it works great.
- logicallee 9y agoout of curiosity why do you know so much about a language that was "mostly irrelevant to you"? Were you forced to develop in it for work, or what happened? For being irrelevant, your comment suggests you've been tracking it super closely (you link a discussion of proposals) ... (quoting you) "since it first came out"!
- twotwotwo 9y agoI just read about and play with things I don't use for work or any real projects--recently-ish I posted about Dart/Flutter here, and I worked through some basic Kotlin exercises after Google announced it as a supported language for Android. ML languages fascinated me early on; I think OCaml was the first language I saw with both strong typing and good type inference to keep code from getting verbose. Once I started looking deeper the pattern matching seemed like a key feature. Stuff like WebKit's new Riptide GC for JS is interesting (concurrent and generational but not copying is a neat corner of the space I hadn't heard much about). Rust is making progress on low-cost memory- and thread-safety. Computers can be interesting! HS/college was a lot of C(++). My work has been Perl (I'm old) and then Python/Django (with the usual sprinkling of other stuff: JS, bash, etc.). Go has been a surprisingly intense hobby over the past few years and it's probably the only lang I could bust something interesting out in soon without much of a learning curve. (I guess also some of the close cousins of JS out there, but not really a brand-new environment then.) I did play with very early (pre-`var`) C# more than 10 years back (I'm old!), but that was before most of these improvements happened and before I understood the relevance of the things like value types that were in there from the start. It's interesting now mostly as another point in the space of programming languages/environments, e.g. different tradeoffs around GC, generics, etc. Guess it has somewhat more potential to be relevant to me as an open/cross-platform project, but it's hard to see myself making the big time investment to actually get up to building-stuff speed in it just for giggles. Similar feelings about Swift or Kotlin, FWIW. (Not that I'm totally ruling anything out, but I've got stuff to do!) That specific discussion of proposals I just Googled up looking for the C# pattern matching stuff. I first heard about it via a different link posted on lobste.rs a while back, but it was faster to Google this than look for that.
- 9y ago
- acangiano 9y agoIt's worth mentioning that C# is one of the most flexible languages available today. Not many languages can claim a great web development, native GUI, native mobile apps, and first-class gaming development, story.
- hossbeast 9y ago"Can be tempting to think of it as a Java clone". C# is superior to Java in every way I can think of. Just a couple examples, unsigned types, simple value types without boxing, and a real generics implementation (java generics are truly awful). The reflection API is c# is also far more useful and easy to understand.
- jayd16 9y agoJava enums are better. Seeing as C# is going to run on more than Windows that's about all I can think of.
- Pxtl 9y agoAnonymous inner classes are more powerful than c# anonymous types. I think c# wins out overall, but there are a few corners where Java has features c# is missing, coming from the fact that c# was a bit more pragmatic where Java was a bit more oop-purist in its origins.
- noblethrasher 9y agoAnonymous delegates (which have been available since 2.0) are the equivalent feature in C#, at least as far as use cases go.
- Pxtl 9y agoWhile anonymous inner classes are more verbose, they're also more powerful because you can create a whole class instead of a single method.
- noblethrasher 9y agoBut, they're equivalently powerful with respect to an API. In Java, a method might expect one instance of a class, to which you can pass an instance of anonymous class, whereas in C# a method might expect a set of delegates, to which you can pass a set of anonymous delegates or lambda expressions. However, thanks to C#'s type inference, it actually ends up being far less verbose, yet more flexible, because anonymous delegates and lambdas can close over local variables. So, strictly speaking, they're more powerful than anonymous inner classes. On the other hand, as someone that greatly admires Smalltalk, I sometimes envy Java's slightly better purity.
- j_s 9y ago> They've done a lot of interesting stuff in the language since it first came out It was always interesting to see which features were just syntactic sugar (and thus backwards compatible) vs. which required runtime support.
- n4r9 9y ago> handy looking stuff like the SustainedLowLatency GC mode Don't forget "server mode" GC. I have a long-running, memory-intensive console app which was taking about 45 minutes to process a typical batch of data. With some profiling I discovered that after the 20 minute mark, most of the time was spent in GC. Some of the classic optimisations (classes to structs, new list to list.clear) helped get the processing down to 30 minutes. After some more Googling I discovered and tried server mode GC. Suddenly it took less than 13 minutes.
- verdex_phone 9y agoThis is pretty cool. Ive seen a surprising number of things hidden in c# that can affect performance. For example stack allocation. Anyway im looking forward to the tools, frameworks, and abstractions that come from these features.
- tomjakubowski 9y agoThis looks great! In other languages, I frequently miss having a simple, widely adopted abstraction like Rust's &[T]; C++ iterators are kind of a pain by comparison, and often feel like an abstraction maybe one level too low/broad (as always, concepts could help that). It's nice that they the documented the interaction with the GC too.
- kccqzy 9y agoI’m not a C# programmer but can someone explain how it deals with memory validity? For example what if after the Span is created the underlying memory is freed or reallocated (e.g. moved to a different region in memory because it needs to grow)? What if I create some data on the stack and then return a Span<T> that points to it? The data on the stack would be implicitly deallocated as the function returns. Basically how does C# solve the iterator invalidation problem in C++?
- deleted 9y ago[deleted]
- int_19h 9y agoThe linked document kinda sorta explains it, by saying that Span is a by-ref type. Let me explain what this actually means. In .NET (below C# level, in the VM itself), there are two fundamental types of pointers - managed (e.g. int&), and unmanaged (e.g. int* ). An unmanaged pointer is basically the same as a C pointer. It points to whatever you tell it to point, and it's your responsibility to ensure that it's still valid when you dereference it. So you can get dangling pointers to locals that went out of scope, for example. If you point it at some memory that is managed by GC, you also need to make sure that GC doesn't automatically move that memory, because the pointer will not be updated - the VM provides an opcode for "pinning" managed objects so that they don't move to facilitate this. Also, because these pointers are "dumb", you can do pointer arithmetic on them, cast them to/from integer types, etc. And they can be used in any position a valid type can. A managed pointer, in contrast, is a pointer that is guaranteed to be memory-safe. For managed pointers that reference managed objects and their fields, this means that GC is aware of those pointers, and adjusts them as it moves the objects around in memory, just like it adjusts regular object references (so you don't need to pin anything; things "just work"). When you have a managed pointer to stack-allocated data, the VM basically makes it illegal to return such a pointer, or stash it away into a variable that can outlive the scope - this is enforced by the bytecode verifier, simply by prohibiting fields of managed pointer types in heap-allocated objects (including, recursively, in any structs). So the only legal operation that you can do with a managed-pointer-to-local is to pass it into a function call - since the stack frame of the calling function is guaranteed to be there for the duration of the call, that is memory-safe. On C# level, unmanaged pointers are just pointers (int* ), and managed pointers are used to implement ref types, as in "void Foo(ref int x)". Until recently, function arguments were really the only place they were permitted, so they were only used to pass arguments by reference. Recently, they've also added the ability to declare ref locals and return by reference, subject to all the verification rules - e.g. if you return a ref, you cannot return a ref to a local, it must be a ref to a field, or a ref argument that you got from the caller. The runtime additionally has some types, that effectively wrap a managed pointer and add some functionality to it. One existing example is TypedReference (https://docs.microsoft.com/en-us/dotnet/api/system.typedreference https://docs.microsoft.com/en-us/dotnet/api/system.typedrefe...) - this is basically a type-erased managed pointer, plus runtime type of whatever it points to. You can then "downcast" it to a proper typed managed pointer, and because it knows the target type, it can verify that the cast is valid. There's also a type called ArgIterator, which is basically the .NET type-safe equivalent of C's va_list. These are used for various low-level stuff like C++/CLI vararg functions. Now, these wrapper types, because they encapsulate a managed pointer, have all the same verification restrictions that managed pointers themselves have. And all these types, including managed pointers themselves, are collectively called by-ref types. Now, Span<T> is basically just a new by-ref type, that combines a managed pointer with span length under the hood. As such, it's subject to all the same restrictions, which together are sufficient to make sure that it's not possible to use it in such a way that it points to invalid memory.
- legohead 9y agoStarting a new job and C# will be a part of it eventually. Reading through this is really confusing -- can anyone recommend me a good book that is relatively up to date? I am good with C and several other languages, so don't need anything that is too newbie-friendly.
- megaman22 9y agoJon Skeet's C# in Depth is pretty solid. The fourth edition isn't done yet - and at the rate of change lately may be out of date by the time it is released, but it goes into some great detail on the guts of the language, and how it has changed over time. https://www.manning.com/books/c-sharp-in-depth-fourth-edition https://www.manning.com/books/c-sharp-in-depth-fourth-editio...
- tonyedgecombe 9y agoI think that book is more useful once you have been using C# for a while, I would recommend it as a starting point.
- deleted 9y ago[deleted]
- sixothree 9y agoC# 7.0 in a Nutshell: The Definitive Reference. It assumes you already know how to program.
- mlazos 9y agoI used C# via CLR for a good ramp up on C# when I started my first job. I came from a java background and the transition was seamless.
- Someone 9y agoYMMV, but I found the language spec a good way to learn the language (not the class library). Concepts are introduced in order, and each section is well-readable. I notice an unofficial draft for C# 6 is available as markdown on https://github.com/dotnet/csharplang/blob/master/spec/README.md https://github.com/dotnet/csharplang/blob/master/spec/README... (via https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/ https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...)
- kuschku 9y agoI’m not sure if I’m missing something, but isn’t this basically just the same as Java 7’s Buffer, ByteBuffer, etc? These, too, support the same types of backing memory (backed by native memory, stack-allocated memory, or a Java array), same access pattern, etc, and are also used by many third-party libraries now for such stuff (including many networking libraries, and graphics libraries such as LWJGL3) What’s so innovative about these?
- zokier 9y ago> I’m not sure if I’m missing something, but isn’t this basically just the same as Java 7’s Buffer, ByteBuffer, etc? Aren't those Java types heap-allocated and GC managed? I think the big deal is that Span can be allocated anywhere (native, stack, heap).
- kuschku 9y agoNope, the wrapper is, but a ByteBuffer also allows different allocation strategies, which is how different libraries use them. For example, LWJGL3 has a separate stack where it allocates them.
- pharrington 9y agoThere is no way to use stack allocated memory in Java. LWJGL's MemoryStack emulates a C style stack by preallocating a set amount of off-JVM-heap memory and decrementing/incrementing an index into it.
- pjmlp 9y ago> There is no way to use stack allocated memory in Java. Not directly, but most JIT compilers do it. It is tricky and fragile, but one can make use of the JIT logs and try to re-write the code so that it takes the right decision regarding escape analysis. As for an actual support at language level, we need to wait for the outcome of projects Valhalla and Panama.
- kuschku 9y ago
- vinutheraj 9y agoNice. Seems very similar to https://github.com/abseil/abseil-cpp/blob/master/absl/types/span.h https://github.com/abseil/abseil-cpp/blob/master/absl/types/...
- teovoinea 9y agoReminds me of slices in Rust.
- zoom6628 9y agoThis will make writing IOT apps easier as one often have to scan/process contiguous buffers. Using string was slow and onerous - this could be cool, and when combined with .NetCore starting to make C# a contender in device space and other low level uses.
- sharpercoder 9y agoI read the blogposts, I have 10 years of C# under my belt (with very scare unsafe usage). Why is this important for me? What problems does this feature solve?
- twotwotwo 9y agoI don't sling C#, but the best I can summarize the doc's claims, it looks like a standard for referencing memory in previously unsupported ways, e.g. for representing a substring of a longer string, or a section of a buffer pool. If you do performance-critical code, you can avoid copying some data or alternatively defining your own ad-hoc slice types. If you don't, optimized libraries that you call will get another tool to minimize data-copying. It will have some limitations, like that it can only be used on the stack. One reason is that the efficient representation on new CLRs will use pointers into the middle of objects and they argue that supporting those on the heap will slow down the GC too much. (Go's approach to non-copying slices/strings was just to support pointers into the middle of allocations, and I guess accept the costs at GC time.) Other reasons relate to concurrency, etc. I can't do much better than that not knowing more about C# and the CLR than I do!
- simooooo 9y agoIf you wanted to replace a bunch of characters in a string. I.e. all 'a' to 'b' you can operate on the span, and not have to re-allocate a new string after each replacement
- mlazos 9y agoThe fact that it can point to unmanaged memory is a benefit for me. Just last week I’ve been porting some performance critical code to C++\CLI and this will allow me to use a span of of object instead of having to pin arrays. One other application is that it is now possible to implement a memory pool using a contiguous piece of memory and only returning slices of it, previously you would have to have multiple instances of a fixed size array in the pool.
- tybit 9y agoThis solves the problem of not allowing low level optimisations in interacting with memory that are C/C++ developers bread and butter. Most C# developers won't use it directly, but rather benefit from wide ranging performance increases in the libraries they use.
- c-smile 9y agoYet another incarnation of slices in D : https://dlang.org/spec/arrays.html#slicing https://dlang.org/spec/arrays.html#slicing in a store near you this time. Yet string_view, vector_view and other range<T>'s in C++. Yet Pythonic slices. Yet Rust.
- WaxProlix 9y agoI don't understand your comment, could you clarify a bit? Are you saying that Python's slice operator is a copy of D's? Or that there's some sort of contiguous memory guarantee with some sort of Sliceable in D? In Python?
- pjmlp 9y agoLanguage features are not relevant on their own. The remaining eco-system needs to be relevant as well.
- nimish 9y agoGlad to see something out of Midori becoming widespread
- pjmlp 9y agoYes. .NET Native and async/await were also influenced by it.
- ComputerGuru 9y agoThe greatest benefit of `Span<T>` in C# is that it allows you to do things that once required an unsafe context in an efficient, (memory) safe, and type-safe manner.
- DubiousPusher 9y agoCan you give an example?
- colejohnson66 9y agoThe Github link has an example: Span<byte> stackSpan; unsafe { byte* stackMemory = stackalloc byte[100]; stackSpan = new Span<byte>(stackMemory, 100); } SafeSum(stackSpan); You still need unsafe to allocate, but once allocated, you can access the memory in a type safe way. M
- justinvp 9y agoUnsafe is no longer necessary for such cases. This can now be written as: Span<byte> stackSpan = stackalloc byte[100]; See https://github.com/dotnet/coreclr/pull/14503/files https://github.com/dotnet/coreclr/pull/14503/files as an example.
- DubiousPusher 9y agoThanks, this is what I was wondering.
- ComputerGuru 9y agoYup. Perhaps the github links can be updated to reflect this awesomeness?
- WalterBright 9y agoD has had slicing since 2001 or so. I proposed them for C a while back: https://digitalmars.com/articles/b44.html https://digitalmars.com/articles/b44.html Slicing is an incredibly useful feature.
- sjmulder 9y agoI see the usefulness of spans, but I'm not sure if they fit well with the C model. Consider these cases: void foo1(char *p, size_t sz); void foo2(char p[2]); If I understand correctly, your proposal applies to the first case. The two arguments could be reduced to one, which is currently not possible for the general case without generic or template structs, but that alone would in my view not be worth introducing fat data types to the standard. An implementation doesn't need the new type either, it can already bounds check deferences of the pointer against the lvalue it was created from[1]. For the second case, I agree that would be nice but it can be worked around by using a struct. [1] "recalling that pointers are anchored to the lvalue from which they were created" Kell, Some Were Meant for C, 2017 (https://sjmulder.nl/dl/pdf/2017%20-%20Kell%20-%20Some%20Were%20Meant%20for%20C.pdf https://sjmulder.nl/dl/pdf/2017%20-%20Kell%20-%20Some%20Were...)
- WalterBright 9y ago> which is currently not possible for the general case Not sure what you're thinking, since it does not require templates or generics, and works for the general case. I know it does, because I implemented it for D without generics or templates. > it can be worked around by using a struct Yes, but nobody does since it is clumsy, hence all the array bounds overflows in C. Even tiny bits of syntactic sugar, which is what this is, can have dramatic and transformative effects. > [1] That inescapably makes all pointers fat pointers, which is far more overhead than what I proposed. My proposal does not have any unavoidable overhead. -- As for implementation experience, the D community finds they work extremely well. It's much more than an "it would be nice" feature.
- sjmulder 9y ago> Not sure what you're thinking, since it does not require templates or generics, and works for the general case. I know it does, because I implemented it for D without generics or templates. This was in favour of your proposal, about how it isn't currently possible to implement this construct generically as a user of the language, hence, it would need to be implemented in the language itself. I think I do see the point you're trying to make. However: > Even tiny bits of syntactic sugar, which is what this is, can have dramatic and transformative effects. This is true, but its use would come mainly from bounds checking at compile time and runtime (otherwise it's just the struct) which is hardly even done for regular arrays.
- Nuzzerino 9y agoI've done some ultra-fast optimizations of algorithms in C# before. Stack allocation and unmanaged pointers was essential for this. It seems that Span<T> is making this approach, in a sense, more accessible to more developers. This makes my optimization skills less valuable as more developers will know how to do this ;) However, this will greatly enhance awareness of C# as a language that can be used for reasonably high-performance code. Most people don't seem to understand how fast C# can be with good optimization techniques. This will help increase adoption of C# in the developer community.
- dr_zoidberg 9y agoOTOH, I'd say this gives you another tool to your optimization toolbox, and one that you can market as "this thing I was doing before with unmanaged pointers, can now be done in a safer way" (and call your previous clients to sell them the new-and-shiny-good-way-to-do-it).
- WorldMaker 9y agoYeah, if Linq optimization work has taught me anything, `Span` will get lumped into "weird advanced things" by most developers and there will still be a role for developers that understand how to use it. (Aside: I still can't believe the number of developers I meet that seem to think of basic Linq concepts like `ToLookup` as "weird advanced things", which leads directly to long rants about `ToList` and why I consider it harmful.)
- Nuzzerino 9y agoYes and no. You're right on the money about Span being an advanced construct. However, before Span, stack allocated memory was essentially C programming in the CLR, and most of the benefits of the CLR (cross architecture compatibility, for one) therefore goes out the window, as you have dependencies on raw memory layout and stack space (determined by the CPU architecture and OS) and things like memcpy, which depend on binaries from the C runtime. If Span does not compromise these benefits, then the developer no longer has to think about those things. There will be an gain in ease of use. Granted, average developers aren't going to care about this (nor will they need to). But you should expect to see an increase in performance of many libraries, as most open source projects generally won't use unsafe code in order to increase performance.
- polskibus 9y agoGreat to see span taking final shape! As for the future, I wish c# had const refs working like in c++ instead of readonly and a plethora of ireadonly collections! It could optimize away many things on the CLR level too. I guess it's not doable without breaking some things, but I think it is worth it.
- benaadams 9y agoreadonly ref/in params in C#7.2? https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/readonly-ref.md https://github.com/dotnet/csharplang/blob/master/proposals/c...
- polskibus 9y agoIt seems like that's a step in the right direction, although as I can see implementation and specification are not finalized so it is hard to say whether any compromises will have to be made when it is released. What I really want is to have some basic code contracts (like pure methods) embedded in the language in as frictionless way as possible. It eliminates need for many simple unit tests, null checks, etc. I'm not sure if this feature will be only for structs or also for classes - I hope both will work. Although I switched to C# 7 years ago from C++, and I like it, I have to say that C++ syntax seems more readable to me - const T& seems more readable to me than ref readonly T. Another thing that might be missing here is propagating immutability information down to JIT. AFAIK, codegen could optimize code better if immutability is guaranteed (at least that's part of the rationale of using const & in C++). There is PureAttribute in System.Diagnostics.Contracts, however CodeContracts seem to be mostly dead in terms of compiler and VS using information from them for static analysis. I wish this ref readonly feature could basically render all IReadOnly* interfaces useless, so that collections would have proper "ref readonly" interfaces. I don't see that in proposal - I wonder if there is a way I could contribute with that remark? I think it makes a good reason that's missing from the rationale on that github page. Lastly, I wish there was more discussion about how C++ or other languages with stronger checks do it. Pretty sure there's huge opportunity to learn on other's mistakes :). As a side note - this is what makes HN great - I can post a comment and get response from Ben Adams himself! One of the greatest .NET Core contributors who made it really fast! Thank you for that link :)
- fulafel 9y agoThey might call the example something other than "SafeSum" as it produces wrong answers on overflow :)
- int_19h 9y agoNot if you compile with -checked+ - then it throws. Although the right way to do this is to use a checked-block: checked { sum += bytes[i]; } It's one obscure C# feature that I rarely see used, but which I find indispensable, and really wish more languages adopted it. Integer overflow vulnerabilities have become more prominent in the past few years, so perhaps there will be some uptake. Interestingly, C# had this feature since the very first release back in 2001.
- wtetzner 9y agoIt would be even better if checked was the default, and you had to use an unchecked block to get unchecked arithmetic.
- benaadams 9y agoCan set it at the project level; then you need to use unchecked instead: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/checked-and-unchecked https://docs.microsoft.com/en-us/dotnet/csharp/language-refe...
- benaadams 9y agoCan't overflow? Is a Span of byte (0-255) being added to a ulong(0-1.8e+19) The maximum value it can produce is much less than a ulong: 2^31 * 255 = 547608330240
- fulafel 9y agoAre Spans limited to 32 bits then?
- alkonaut 9y agoC# 7.0 works for the most part in .NET 4.5 or even 4.0 Here it seems there is a dependency on the 4.7 runtime, is this the case? Where can I see a matrix of what C# versions work on which (full/desktop) runtimes?
- kevingadd 9y agoSpan definitely requires VM updates (Mono has been picking up commits to support it) so that feature at least is not going to work on 4.5/4.0 without a polyfill.
- benaadams 9y agoYou can use the NuGet package for downlevel support https://www.nuget.org/packages/System.Memory/ https://www.nuget.org/packages/System.Memory/ The runtime changes make it faster, smaller and include Jit optimizations for it (bounds check elimination etc)
- benaadams 9y agoYou can use the NuGet package for 4.5+ (check Dependencies section) https://www.nuget.org/packages/System.Memory/# https://www.nuget.org/packages/System.Memory/# The later runtime changes make it faster
- alkonaut 9y agoI’m most excited for the “value types as references” such as ref returns an “in”-parameters. I often use arrays of structs for memory locality, and they often grow larger than the size where they can be passed in registers. In a 64bit app with all double precision floats there isn’t much you can do with 16 bytes or less. Being able to send 3 structs of e.g 32 bytes each (such as Vector4<double>) to a function without hidden copying will be great.
- bhouston 9y agoI wrote an incredible similar class for protected memory accesses for c++ back in 2008. Lead to beautiful code and in debug mode it could verify accesses. Subsets, copies, type conversions etc were beautiful. Also combined it with a shared pointer class as well. Probably should open source those...
- chiph 9y agoGlad to see that they'll help devs with the pinned memory issue (for buffers used with IO Completion Ports). But had to look up what "RIO Sockets" were - turns out the API helps you pre-register your buffers. Something you had to "just know" to do before.
- manojlds 9y agoCan someone update the link to https://github.com/dotnet/corefxlab/blob/49982d193b4853002a960770166713da858ef8da/docs/specs/span.md https://github.com/dotnet/corefxlab/blob/49982d193b4853002a9...