Classic ASP InStr() Evaluates True on Empty Comparison String

asp-classicvbscript

I ran into an issue with the Classic ASP VbScript InStr() function. As shown below, the second call to InStr() returns 1 when searching for an empty string in a non empty string. I'm curious why this is happening.

' InStr Test
Dim someText : someText = "So say we all"
Dim emptyString : emptyString = ""

'' I expect this to be true
If inStr(1,someText,"so",1) > 0 Then
    Response.write ( "I found ""so""<br />" )
End If 

'' I expect this to be false
If inStr(1, someText, emptyString, 1) > 0 Then
    Response.Write( "I found an empty string<br />" )
End If

EDIT:
Some additional clarification: The reason for the question came up when debugging legacy code and running into a situation like this:

Function Go(value)
     If InStr(1, "Option1|Option2|Option3", value, 1) > 0 Then
          ' Do some stuff
     End If
End Function

In some cases function Go() can get called with an empty string. The original developer's intent was not to check whether value was empty, but rather, whether or not value was equal to one of the piped delimited values (Option1,Option2, etc.).

Thinking about this further it makes sense that every string is created from an empty string, and I can understand why a programming language would assume a string with all characters removed still contains the empty string.

What doesn't make sense to me is why programming languages are implementing this. Consider these 2 statements:

InStr("so say we all", "s") '' evaluates to 1
InStr("so say we all", "")  '' evaluates to 1

The InStr() function will return the position of the first occurrence of one string within another. In both of the above cases, the result is 1. However, position 1 always contains the character "s", not an empty string. Furthermore, using another string function like Len() or LenB() on an empty string alone will result in 0, indicating a character length of 0.

It seems that there is some inconsistency here. The empty string contained in all strings is not actually a character, but the InStr() function is treating it as one when other string functions are not. I find this to be un-intuitive and un-necessary.

Best Answer

The Empty String is the Identity Element for Strings:

The identity element I (also denoted E, e, or 1) of a group or related mathematical structure S is the unique element such that Ia=aI=a for every element a in S. The symbol "E" derives from the German word for unity, "Einheit." An identity element is also called a unit element.

If you add 0 to a number n the result is n; if you add/concatenate "" to a string s the result is s:

>> WScript.Echo CStr(1 = 1 + 0)
>> WScript.Echo CStr("a" = "a" & "")
>>
True
True

So every String and SubString contains at least one "":

>> s = "abc"
>> For p = 1 To Len(s)
>>     WScript.Echo InStr(p, s, "")
>> Next
>>
1
2
3

and Instr() reports that faithfully. The docs even state:

InStr([start, ]string1, string2[, compare])
...
The InStr function returns the following values:
...
string2 is zero-length            start

WRT your

However, position 1 always contains the character "s", not an empty string.

==>

Position 1 always contains the character "s", and therefore an empty string too.

Related Topic