<p>In C, <code>fopen()</code> uses string literals such as <code>&quot;r&quot;</code> or <code>&quot;r+&quot;</code> or <code>&quot;w&quot;</code> to specify the mode with which to open a file. One possible reason for this I read is at the time C was so new that there might not have been a convenient way to create predefined constants.</p>
<p>However, the function <code>fseek()</code> which is part of the same file IO library uses predefined constants <code>SEEK_SET</code> <code>SEEK_CUR</code> and <code>SEEK_END</code> to specify the mode.</p>
<p>What was the motivation for using, at least what I consider a substandard approach for flag parameters for <code>fopen()</code> but not <code>fseek()</code>? If <code>fseek()</code> could use predefined constants as flags, why could <code>fopen()</code> not?</p>

<c><history><io>
What prevented fopen() from utilizing macros/flags but not fseek()?
CC BY-SA 4.0
2024-04-29T23:31:44.107Z
Where did you read this? Citation?
Nate Eldredge
CC BY-SA 4.0
2024-04-29T23:36:09.047Z
The natural way to use macro constants for fopen would have been with bitmasks, like Unix 'open' does. But I can't think of any place in the classic C standard library where bitmask constants are used, so maybe they wanted to avoid them for some reason.
Nate Eldredge
CC BY-SA 4.0
2024-04-29T23:44:16.687Z
I think, `fseek()` came later and probably the reason was that it used some file descriptor-based `seek()` syscall. But that is only hyphotese. Kerrigan could say, why has it so happened.
peterh
CC BY-SA 4.0
2024-04-30T20:54:26.123Z
Questions about the history of a language might be more appropriate for [retrocomputing.se].
Barmar
<p>I agree that this API choice of using strings instead of some form of more structured data is maybe not great. But your question is about why should we expect a difference between these designs?</p>
<p>For <code>fseek</code> there really are only a handful of possibilities and there are unlikely to be more. But for <code>fopen</code>, many implementations of this library method support additional options in that string parameter. For example, to open a UTF-8 text file:</p>
<pre><code>FILE *fp = fopen(&quot;newfile.txt&quot;, &quot;rt+, ccs=UTF-8&quot;);
</code></pre>
<p>Microsoft's implementation has <em>dozens</em> of extensions to the string argument; see <a href="https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170" rel="noreferrer">https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170</a> for a list.</p>
<p>In short, it's an extension point for standard library implementations to take advantage of. Whether that was a <em>motivation</em> for the design, or a happy historical accident, I do not know.</p>

CC BY-SA 4.0
2024-04-30T00:20:22.743Z
2024-04-30T00:28:15.517Z
2024-04-30T00:28:15.517Z
Eric Lippert
# What prevented fopen() from utilizing macros/flags but not fseek()?
Posted by: username_0 on 2024-04-29
In C, `fopen()` uses string literals such as `"r"` or `"r+"` or `"w"` to specify the mode with which to open a file. One possible reason for this I read is at the time C was so new that there might not have been a convenient way to create predefined constants.

However, the function `fseek()` which is part of the same file IO library uses predefined constants `SEEK_SET` `SEEK_CUR` and `SEEK_END` to specify the mode.

What was the motivation for using, at least what I consider a substandard approach for flag parameters for `fopen()` but not `fseek()`? If `fseek()` could use predefined constants as flags, why could `fopen()` not?
**Tags:** c history io
> **Comments:**
> **username_1**: Where did you read this? Citation?  
> **username_1**: The natural way to use macro constants for fopen would have been with bitmasks, like Unix 'open' does. But I can't think of any place in the classic C standard library where bitmask constants are used, so maybe they wanted to avoid them for some reason.  
> **username_2**: I think, `fseek()` came later and probably the reason was that it used some file descriptor-based `seek()` syscall. But that is only hyphotese. Kerrigan could say, why has it so happened.  
> **username_3**: Questions about the history of a language might be more appropriate for [retrocomputing.se].  
---
## 1 answers
### Answer by username_4 on 2024-04-30. Score: 6
I agree that this API choice of using strings instead of some form of more structured data is maybe not great. But your question is about why should we expect a difference between these designs?
For fseek there really are only a handful of possibilities and there are unlikely to be more. But for fopen, many implementations of this library method support additional options in that string parameter. For example, to open a UTF-8 text file:
FILE *fp = fopen("newfile.txt", "rt+, ccs=UTF-8");

Microsoft's implementation has dozens of extensions to the string argument; see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/fopen-wfopen?view=msvc-170 for a list.
In short, it's an extension point for standard library implementations to take advantage of. Whether that was a motivation for the design, or a happy historical accident, I do not know.
---
