SEP
21

Whenever I get a new batch of used cartridge games I open them up and tidy up the insides. This is a good opportunity to change old batteries, and an oddly large number of gamers somehow manage to spill entire cans of Coke into their games, leaving them in desperate need of a cleaning.

One game, however, seemed a bit off. The game ran okay, but would not save... Sure enough, it was a counterfeit cartridge. Not only is it poorly-made, but it uses battery-backed SRAM instead of the flash memory present in the authentic cartridge. Judging by the fact that the battery is already dead, it's likely cheap SRAM (instead of nicer low-power SRAM), or a cheap battery, or both.

Counterfeit

Counterfeit Cartridge

Authentic

Counterfeit Cartridge

To avoid getting another fake in the future, I wanted to pick out a few things that differ. Better counterfeits could be out there, but at least this will help my odds. The insides are a dead giveaway, but most times I can only look at the outside before buying. The following things can be seen without disassembly, and differentiate the fake from any of my authentic ones.

Connector Should Not Have Holes

The gold pads on the connector should not have circuit connection holes in them.

Label Should Have Imprints

If you angle the cartridge just right, you can see a reflection off the label's coating. In addition to showing off every scratch that's ever landed on the cartridge, the reflection should reveal one or more 2-character codes indented into the label.

20:

Counterfeit Cartridge

09 and E8:

Counterfeit Cartridge

E4:

Counterfeit Cartridge

None! Fake:

Counterfeit Cartridge

Plastic Opposite The Connector Should Be Marked

The plastic face opposite the connector normally has some markings on it. The counterfeit cartridge was just flat plastic with no markings.

Normal markings:

Counterfeit Cartridge

SEP
20

PHP has plenty of oddities, so it’s probably not too surprising that it’s making an appearance in a WTF post. The sample below is pretty simple. You can see what the “sensible” output would be, and can probably guess what the real output will be (as this is a WTF post, afterall).

<?php
$a =
"12345678901234567890";
$b =
"12345678901234567123";

if ($a == $b)
{
    echo
"$a == $b";
}
else
{
    echo
"$a != $b";
}
?>

The output:

12345678901234567890 == 12345678901234567123

Many weakly-typed languages perform implicit type conversion to make it easy to compare two variables of different types (e.g. 123 == “123”, or false == 0), but the variables above are just two strings. What’s going on?

Answer (highlight the text below):

A simple string comparison operator might compare each character in a string to the character at the same position in the other string, then return false if any pair of characters differ. PHP does things a bit differently. In this case, the PHP comparison:

- Scans the string to determine if it contains a number
- Converts the string to a number
- Performs a numeric comparison

PHP strings can be of an arbitrary length, but numbers are a fixed size (double-precision IEEE floating-point values in this case). Hence, converting the strings to numbers loses precision. After discarding some precision, the two numbers above are equal (they are both 1.2345678901234567E+19).

How could this cause trouble? Consider this: PHP is commonly used to run websites, and website credentials are often stored as a hash string in a database. No matter how strong of a hashing algorithm is used, if the strings appear to be numeric, the “==” operator will only compare the first ~17 characters to determine if the hashes match.

wtf
SEP
16

High-level language abstractions save lots of development time, but understanding how they work underneath can help you steer clear of problems. This post details how common languages (such as C#) consume optional parameters. A different compiler could, of course, do something different.

As noted in the previous post, marking a parameter as optional just sets some flags in the the metadata; the method implementation still expects values for each parameter to be passed in. Thus, the default parameter-insertion must take effect at the call site. If the calling source code doesn’t specify a value for some of the parameters, the compiler can insert values for each of the unspecified parameters (which it can obtain from the default-value specification in the metadata). By doing this, the source code can omit values for some parameters, but the compiled method call will always specify a value for each parameter.

Below are a couple common issues that can arise from default-parameter use. You can avoid these problems by always remembering: default values are inserted at the call site.

Versioning

As with any compile-time value insertion, problems can arise with versioning if the value is exposed in one assembly and inserted into another. A simple example can illustrate this behavior:

Library.dll

void ConnectToServer(string server = "someserver.com")
{
    
// ...
}

Client.exe

static void Main()
{
    ConnectToServer();
}

This code would, of course, invoke the ConnectToServer method with “someserver.com” as the parameter value. Some time later, a new version of the library is released. One of the various updates is a new default server that clients should use.

Library.dll version 2

void ConnectToServer(string server = "newserver.com")
{
    
// ...
}

If you drop version 2 of the library DLL into the application folder, the client will continue to pass the value “someserver.com”, even though the new library specifies the default as “newserver.com”.

The default value is read at compile time and inserted into the call site. The argument being passed - “someserver.com” - has been copied into the client assembly, and the client has not changed. If you recompile the client (with no source code changes) it will switch to passing the value “newserver.com”.

Types

Consider the following application:

using System;

interface IServer
{
    
void Start(int port = 1234);
}

class TcpServer : IServer
{
    
public virtual void Start(int port)
    {
        
Console.WriteLine("TcpServer running on port {0}", port);
    }
}

class HttpServer : TcpServer
{
    
public override void Start(int port = 80)
    {
        
Console.WriteLine("HttpServer running on port {0}", port);
    }
}

class Program
{
    
public static void Main()
    {
        
HttpServer httpServer = new HttpServer();
        RunServer(httpServer);
    }

    
public static void RunServer(IServer server)
    {
        server.Start();
        
Console.WriteLine("Server started");

        
while (true)
        {
            
// Handle requests...
        }
    }
}

The output?

HttpServer running on port 1234
Server started

That's the Console.WriteLine() from HttpServer.Start(), but the default value from IServer.Start(). What's going on?

Because default parameter values are inserted by the compiler, they can only make use of information that’s available at compile time to determine the most appropriate value. Specifically, only the reference type is known at compile time; the type of the actual object is only known at runtime. Virtual method selection, on the other hand, is carried out at runtime. Normal virtual-method rules still apply, so the most-derived method available at runtime will be invoked.

In the example above, the HttpServer implementation of Start() will be run regardless of the reference type used to invoke it, as it is the most-derived implementation. The default parameter passed to HttpServer.Start(), however, will vary depending on the type of reference used to invoke HttpServer.Start(). Given a single instance of HttpServer, the default value for the “port” argument is “1234” if invoked from an IServer reference, 80 if invoked from a HttpServer reference, and has no default value for a TcpServer reference (i.e. calling Connect() on a TcpServer-typed reference to an HttpServer object will not compile unless “port” is specified explicitly).

HttpServer httpServer = new HttpServer();
TcpServer tcpServer = httpServer;
IServer server = tcpServer;

httpServer.Start();
// Passes port 80
tcpServer.Start();
// Does not compile
server.Start();
// Passes port 1234
SEP
12

C# 4.0 added an “optional parameters” feature. This feature allows a method to specify default values for some parameters and allows callers to omit values for those parameters. It’s always important to distinguish features of a language (e.g. C# 4.0) from features of the framework (e.g. .NET 4.0). Optional parameters in C# were exposed in C# 4.0, but were supported by the .NET framework all the way back to .NET 1.0.

How They Work

Optional parameters are strictly a convenience feature offered by various language compilers. In CIL, there is no such thing as an optional parameter; there aren’t any markers to indicate how many arguments were specified, nor are there special “empty” arguments you can pass in place of an actual value. The CIL instructions that invoke methods always specify values for all parameters. If a method accepts two arguments, it will always read those two arguments from the stack. If you push fewer than two arguments onto the stack, the method will still just read whatever two values happen to be at the top of the stack, or exhaust the stack trying to read two values, or (most likely) just fail to run as the code will fail the verification step.

The high-level code (C#/VB/etc.) can omit values for some parameters of a call, but the resulting CIL sequence does specify these values... clearly the compiler is inserting the values during compilation. So where does the compiler look for default values, and how does it determine that the parameter is optional in the first place?

As with most features that don’t actually affect the CIL, optional parameters are described entirely in the metadata. Method parameter metadata can have a flag indicating that the parameter is optional. There is also a flag indicating whether the parameter has a default value (and a corresponding entry in the Constants table containing the value). The “optional” flag indicates that a compiler may want to let code omit this parameter, and silently insert the default value for the type (null for objects, 0 for integers, etc.). The “default value” flag indicates that there is an explicit default value that should be inserted instead of the type default.

If a language compiler is willing to look for this metadata, it can populate method arguments automatically. If the compiler doesn’t support optional parameters, it can simply ignore this metadata and require all parameters to be specified explicitly in the source code. Prior to version 4.0, the C# compiler was in the latter camp. As of C# 4.0, the compiler takes this metadata into account when compiling method calls and will insert the default values where appropriate.

C# isn’t the only language in town, and some other languages (such as VB.NET) made use of optional parameters long before C#. Interestingly, in the spirit of interoperability, C# gained the ability to mark parameters as optional long before C# 4.0, but lacked the ability to consume this flag. In other words, the compiler had logic to generate optional-parameter metadata when compiling method implementations, but did not look at that metadata when compiling method calls.

C# 1.0 / 1.2

If the Optional custom attribute was applied to a parameter in a method declaration, the compiler set the “optional” flag on the parameter metadata (and did not emit the attribute entry in the metadata). The compiler did not take the “optional” flag (or the “default-value” flag) into account when compiling method calls. Thus, libraries could expose methods with optional parameters, but could not specify the default value. If called from C#, all arguments had to be specified explicitly.

C# 2.0

If the DefaultParameterValue custom attribute was applied to a parameter in a method declaration, the compiler set the “default-value” flag on the parameter metadata and created an entry in the Constants table containing the value (and, again, did not emit the attribute as an actual attribute entry in the metadata). The compiler still ignored the presence either flag when compiling method calls. Libraries could expose methods with optional parameters and default values, but C# callers still had to specify all arguments explicitly.

C# 4.0

New syntax was added to specify default values: parameter names can be followed by an equals sign and a value. If a default value is specified, both the “optional” and “default-value” flags are set in the parameter metadata, and the default value is stored in the Constants metadata table. The following two samples are equivalent in C# 4.0:

void DoSomething(int parameter = 123)
void DoSomething([Optional, DefaultParameterValue(123)] int parameter)

In addition, the C# 4.0 compiler examines the “optional” and “default-value” flags when compiling a method call, and will insert any optional values that haven’t been explicitly specified. C# 4.0 able to consume default parameters.

Wrapping Up

In summary, all versions of C# can make methods with optional parameters. C# 2.0 added the ability to specify default values on those parameters, and C# 4.0 added the ability to consume optional parameters.

Interestingly, even though the void Method(int parameter = 123) syntax was only added in C# 4.0, all of the previous compilers went out of their way to detect it and tell users that it’s not supported.

error CS0241: Default parameter specifiers are not permitted

Details for the error can be found on MSDN:

http://msdn.microsoft.com/en-us/library/294000kk(v=vs.71).aspx