title: Does ISO C allow aliasing of the argv[] pointers supplied to main()?
body: <p>ISO C requires that hosted implementations call a function named <code>main</code>. If the program receives arguments, they are received as an array of <code>char*</code> pointers, the second argument in <code>main</code>'s definition <code>int main(int argc, char* argv[])</code>.</p>
  
  <p>ISO C also requires that the strings pointed to by the <code>argv</code> array be modifiable.</p>
  
  <p>But can the elements of <code>argv</code> alias one another? In other words, can there exist <code>i</code>, <code>j</code> such that</p>
  
  <ul>
  <li><code>0 &gt;= i &amp;&amp; i &lt; argc</code></li>
  <li><code>0 &gt;= j &amp;&amp; j &lt; argc</code></li>
  <li><code>i != j</code></li>
  <li><code>0 &lt;  strlen(argv[i])</code></li>
  <li><code>strlen(argv[i]) &lt;= strlen(argv[j])</code></li>
  <li><code>argv[i]</code> aliases <code>argv[j]</code></li>
  </ul>
  
  <p>at program start-up? If so, a write through <code>argv[i][0]</code> would also be seen through the aliasing string <code>argv[j]</code>.</p>
  
  <p>The relevant clauses of the ISO C Standard are below, but do not allow me to conclusively answer the titular question.</p>
  
  <blockquote>
    <h3>§ 5.1.2.2.1 Program startup</h3>
    
    <p>The function called at program startup is named <code>main</code>. The implementation declares no prototype for this function. It shall be defined with a return type of <code>int</code> and with no parameters:</p>
  
  <pre><code>int main(void) { /* ... */ }
  </code></pre>
    
    <p>or with two parameters (referred to here as <code>argc</code> and <code>argv</code>, though any names may be used, as they are local to the function in which they are declared):</p>
  
  <pre><code>int main(int argc, char *argv[]) { /* ... */ }
  </code></pre>
    
    <p>or equivalent; 10) or in some other implementation-defined manner.</p>
    
    <p>If they are declared, the parameters to the <code>main</code> function shall obey the following constraints:</p>
    
    <ul>
    <li>The value of <code>argc</code> shall be nonnegative.</li>
    <li><code>argv[argc]</code> shall be a null pointer.</li>
    <li>If the value of <code>argc</code> is greater than zero, the array members <code>argv[0]</code> through <code>argv[argc-1]</code> inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment. If the host environment is not capable of supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the strings are received in lowercase.</li>
    <li>If the value of <code>argc</code> is greater than zero, the string pointed to by <code>argv[0]</code> represents the program name; <code>argv[0][0]</code> shall be the null character if the program name is not available from the host environment. If the value of <code>argc</code> is greater than one, the strings pointed to by <code>argv[1]</code> through <code>argv[argc-1]</code> represent the program parameters.</li>
    <li>The parameters <code>argc</code> and <code>argv</code> and the strings pointed to by the <code>argv</code> array shall be modifiable by the program, and retain their last-stored values between program startup and program termination.</li>
    </ul>
  </blockquote>
  
  <p>By my reading, the answer to the titular question is "yes", since nowhere is it explicitly forbidden and nowhere does the standard urge or require the use of <code>char* restrict*</code>-qualified <code>argv</code>, but the answer might turn on the interpretation of <em>"and retain their last-stored values between program startup and program termination."</em>.</p>
  
  <p>The practical import of this question is that if the answer to it is indeed "yes", a portable program that wishes to modify the strings in <code>argv</code> must first perform (the equivalent of) POSIX <code>strdup()</code> on them for safety.</p>