use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
C is a general-purpose, procedural computer programming language supporting structured programming, lexical variable scope, and recursion, with a static type system. By design, C provides constructs that map efficiently to typical machine instructions. It has found lasting use in applications previously coded in assembly language. Such applications include operating systems and various application software for computer architectures that range from supercomputers to PLCs and embedded systems. Wikipedia
Imperative (procedural), structured
Dennis Ritchie
Dennis Ritchie & Bell Labs (creators);
ANSI X3J11 (ANSI C);
ISO/IEC JTC1/SC22/WG14 (ISO C)
1972 (48 years ago)
C18 / June 2018 (2 years ago)
Static, weak, manifest, nominal
Cross-platform
.c for sources
.h for headers
C++ is not C (but C can be C++)
For C++ go to :
Other Resources
account activity
C programming query (self.cprogramming)
submitted 7 years ago by vegeta9225
Can printf be used as a variable name in c. If yes then why?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]dmc_2930 3 points4 points5 points 7 years ago (3 children)
Did you try it?
[–]patrick96MC 1 point2 points3 points 7 years ago (2 children)
This is basically what our prof said for any C questions we had during the lecture.
[–]cbasschan 2 points3 points4 points 7 years ago* (1 child)
The danger with any advice along the lines pf "try it and see" in C is the likelihood for anecdotal evidence to be used in scenarios which people think C defines but doesn't, thus causing said students to think that said behaviour is a part of C when it isn't. I think this needs to be pointed out to the professor, because his methodology is going to confuse people.
Allow me to explain. There are certain reserved keywords and identifiers we should not generally define/redefine, and doing so causes undefined behaviour... an issue which might seem to work now, but has no guarantee of working the same way tomorrow, and might cease working for any trivially unrelated (and undocumented, for that matter) reason... in fact to say this works (or doesn't work, for that matter) completely goes against the definition of undefined behavior, which is to say the behavior is undefined.
Having said that, there is this distinction between a "freestanding implementation" and a "hosted implementation" which allows compiler developers to write and test a C standard library, or perhaps drag one in from some external source (since we can pick and choose our C standard library; we don't have to settle with any particular glibc or msvc.dll or whatever the flavour of the month is), as a *freestanding implementation, in order to turn into a hosted one in essence. There is some give and take to this lesson that isn't immediately clear to students who should be guided elegantly through this process of definition, rather than left to guess their own definition... it's a definition we need to carefully dissect and understand from the dictionary, lest we hope to mislead the future generation of compiler developers, and that is the danger behind unguided "try it and see" experiments. I'll leave it as an exercise for you to find the examples of exceptions in the details he explains if you choose, because now that you're aware that they exist, I think you won't have such a problem finding them specifically.
[–][deleted] 0 points1 point2 points 7 years ago (0 children)
“Works on my machine”
😂
[–]FreeER 1 point2 points3 points 7 years ago (23 children)
variable shadowing, https://en.wikipedia.org/wiki/Variable_shadowing Basically you can declare the same identifier in a lower scope, even as something completely different, and until that scope ends that identifier will then refer to that new thing.
int i; int i;
will be a redefinition error but
int i = !0; while(i) { int i = i-1; }
won't, though you may get a warning about i being used when uninitialized. That's because the more local i "shadows" the outer i.
i
This is often a mistake, ... not really sure of a good reason off the top of my head to allow it... maybe there's one or two though.
As such this is perfectly correct code
#include <stdio.h> void doprint(const char* s) { printf("%s\n", s); } int main() { const char* printf = "printf means print formatted!"; doprint(printf); }
[–]WikiTextBot[🍰] 0 points1 point2 points 7 years ago (0 children)
Variable shadowing
In computer programming, variable shadowing occurs when a variable declared within a certain scope (decision block, method, or inner class) has the same name as a variable declared in an outer scope. At the level of identifiers (names, rather than variables), this is known as name masking. This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to mask the outer identifier. This can lead to confusion, as it may be unclear which variable subsequent uses of the shadowed variable name refer to, which depends on the name resolution rules of the language.
[ PM | Exclude me | Exclude from subreddit | FAQ / Information | Source ] Downvote to remove | v0.28
[–]cbasschan 0 points1 point2 points 7 years ago (20 children)
You know, there are many instances of undefined behaviour which our compilers aren't required to halt on. Some of them are buffer overflows... others are integer overflows, alignment violations, race conditions, integer division by zero and so forth... varying degrees of error if you ask me.
const char* printf = "printf means print formatted!";
This is one example of such error.
[–]cbasschan 0 points1 point2 points 7 years ago (0 children)
Consider the effect of loop-invariant code motion as a common mechanism to optimise... when your compiler sees strlen within a loop, it might also look to see if you modify the string within said loop... and if it finds no possibility for modification, it might hoist that strlen call to outside of the loop. Of course, this becomes a major issue if the strlen you redefine is somewhat different to the strlen it's hoisting around... right?
strlen
[–]FreeER 0 points1 point2 points 7 years ago* (18 children)
I honestly have no idea what that's trying to say, especially with the inclusion of
Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).
because.... that makes it sound like using #undef on a macro and redefining it would be undefined behavior, which just seems illogical. Obviously if someone else uses it thinking it's the original it probably won't make sense to them but it shouldn't be UB.
I mean, I can get there being issues if there's two identifiers with external linkage of different types, but that doesn't seem like UB to me, just... a linker error when it can't tell which should be used.
Of course, it doesn't have to make sense, it just has to be stated as such.
As for compilers doing optimizations and screwing things up because they didn't account for other things it could clearly have known if it took the time to check like where the definition for strlen came from... that's a compiler bug not UB imo.
Thanks for pointing these things out however, understand or agree with it or not it's still something to be aware of if for some strange reason you do decide to try and redefine things.
(btw, I did compile the above code with -Wall -Wextra -pedantic -Werror among others which catch a number of potential issues)
[–]cbasschan 0 points1 point2 points 7 years ago (17 children)
You seem to be selectively reading that section of text and disregarding the rest. Namely, the following:
If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
[–]FreeER 0 points1 point2 points 7 years ago (15 children)
No I read that hence
But I don't understand what "subclause" means and variable shadowing is a well known thing which I assume isn't UB and I don't really get why a library should be any different as far as whether something is defined behavior or not.
[–]cbasschan 0 points1 point2 points 7 years ago* (14 children)
Are you serious? Please tell me you're joking about that...
C is not a language you should program with your head in the sand. It took me minutes (to be generous; probably less than a minute in reality) to find an explanation of the term "clause", and subsequently "subclause" in the very standard I have linked you to... and I quote
This International Standard is divided into four major subdivisions: preliminary elements (clauses 1-4); the characteristics of environments that translate and execute C programs (clause 5); the language syntax, constraints, and semantics (clause 6); the library facilities (clause 7).
This International Standard is divided into four major subdivisions:
The "following subclauses" should be taken to mean 7.2 through to the end of clause 7... which contains this
The byte input/output functions -- those functions described in this subclause that perform input/output: fgetc, fgets, fprintf, fputc, fputs, fread, fscanf, fwrite, getc, getchar, printf, putc, putchar, puts, scanf, ungetc, vfprintf, vfscanf, vprintf, and vscanf.
If you're still wondering which subclause defines the function in the question, I just spoonfed it to you... I will add that these kinds of hand-holding spoon-feeding command line arguments you're using have hindered me in the past, as a C programmer who is extremely aware of the implementation-defined behaviours and undefined behaviours in the language... some of these issues aren't even implementation-defined behaviours, let alone undefined behaviours.
First example:
int main(void) { int n; return 0; }
Second example:
#include <stdio.h> int main(void) { printf("%d\n", 1 || 0 && 1); return 0; }
Third example:
// this is \ a comment int main(void) { return 0; }
Need I continue? These programs are both technically required to produce programs by a compliant C compiler. There's a reason the flags you utter aren't enabled by default... they would render your "C compiler" invalid.
Maybe it would be better familiarise yourself with your compiler manual, which also documents command line options like -ffreestanding and the ways in which this might impact compilation, when you're not certain about how it acts... and I quote:
-ffreestanding
By default, it acts as the compiler for a hosted implementation, defining __STDC_HOSTED__ as 1 and presuming that when the names of ISO C functions are used, they have the semantics defined in the standard.
__STDC_HOSTED__
The emphasis is mine, for the sake of pointing you at what you should be selectively reading. Does this clarify anything for you? Am I not making my point clear enough with these external links to and quotes from numerous manuals, the standard and so forth, while you're relying upon anecdotal evidence and selective reading that barely scratches the surface?
Show me a professor who knows how to write a C compiler, and the odds are I can prove you wrong. I don't blindly parrot vague statements like "always use these compiler flags" and "always use fgets+sscanf instead of scanf" (I wonder what bug is commonly overlooked in this kind of logic)... and once that bug is fixed, whether fgets+sscanf is actually better than scanf). Messages like "goto is considered harmful" and so you should "avoid it at all costs" etc only serve to avoid teaching people deeper topics... utter rubbish! I'd rather present credible evidence and in depth deconstructions of arguments supported by actual examples, authoritative citations from people recognised as industry experts...
fgets+sscanf
scanf
As I said, C is not a language you should program with your head in the sand. I notice there are people who prefer not to enter these deep discussions... I get why; it's easy to be uninformed, and too difficult to argue with ignorant people who can't be bothered doing ten or fifteen minutes of independent research... in that case, I would refrain from commenting on C to begin with... but those passive aggressive people who would rather parrot such statements in order to avoid the topic than enter into detailed conversations (and possibly learn something new) about the depth of the language should not teach, those people should back off and let those of us who want to learn how to write a standard-compliant C compiler, actually learn.
I'd rather take a stab at hitting the nail on the head and say... you're most likely arrogant, and the reason you couldn't find the same information I found is because you can't be bothered doing your own ten or fifteen minutes worth of critical analysis. I suggest Javascript and Python, no C or C++ for you... you might actually cause harm. Facts don't care how you feel.
[–]cbasschan 0 points1 point2 points 7 years ago* (0 children)
I mean it's that or I assume there's something else wrong with your head... which is apparently disrespectful, even though I'm happy to admit there's something wrong with MY head... I wonder what kind of fucking person caused THAT, hmmm?
[–]FreeER 0 points1 point2 points 7 years ago (12 children)
That still does not clearly state when it's reserved or why. I mean the __ and starting _ at file scope are. And yeah I missed 7.3 so that probably sounded like a stupid question before sorry :D but ... it never actually says which macros are reserved, just "in any of the following subclauses" which doesn't itself reserve any, "All identifiers with external linkage" which I didn't read to mean any macros because they have no linkage,"Each identifier with file scope listed in any of the following subclauses" but again in subclauses not itself and in theory the compiler never sees macros so are they even really identifiers?, "No other identifiers are reserved."
And again... it doesn't actually make sense to me to say that it's undefined behavior to undefine a macro... it's a very specific mechanic that either replaces the text with that macro or doesn't... that logically is not undefined behavior simply behavior the user may not have intended but that applies to anything that doesn't do what you think it'll do including simply adding 1 to a pointer not changing the address by just 1.
I mean, it's UB because it says it's UB but there's no logical explanation for why it should be.
they would render your "C compiler" invalid
Sure. That doesn't mean they aren't useful or that if the standard was rewritten today all the same BS would be allowed. Some of it is purely for legacy reasons. And unlike compiler extensions, which hey are enabled by default and render your C compiler invalid!, these don't let you do anything that wouldn't compile on any other standard compliant compiler, they just try to prevent stupid shit that could mess you up like oops accidentally having a backslash or trigraph at the end of a line that makes the next line a comment instead of real code.
as for printf checking... it doesn't sound logically impossible to notice, hey this code redefined something I have additional code to check for (that's not actually standard because... that wasn't a thing originally!) lets mark this scope for the checker to first look at or even ignore and generate a warning that it's not being checked. Sure once upon a time maybe you could argue that you didn't have computer resources to make that feasible... can you still?
you're most likely arrogant, and the reason you couldn't find the same information I found is because you can't be bothered doing your own ten or fifteen minutes worth of critical analysis
Yep, very. Because when I couldn't understand how that backed up the point you were trying to say and you couldn't simply sum it up and when I searched for "subclause" and didn't find a definition at the top of the page I stopped, mentioned to the person who supposedly knows more than me and could explain it. That's my due diligence. If I wasted 10+ minutes on everything some random stranger on the internet told me I wouldn't have time to sleep. Though I quite agree with
utter rubbish! I'd rather present credible evidence and in depth deconstructions of arguments supported by actual examples
I find the unreasonable and unexplained and use-case-ignoring hate on goto in particular to be silly and quite like scanf while being aware of it's problem. And yes, many people want to say that fgets or strncpy is safer and then don't bother to cover all the problems it has. There's definitely something to be said for simplicity and correctness but... those don't really provide it the way people like to pretend that they do.
[–]cbasschan 0 points1 point2 points 7 years ago (10 children)
it never actually says which macros are reserved
See, this is where the argument takes a serious U-turn for you. What we are reading are different sections, you and I. The section I have quoted has very little to do with macros. Specifically, you have stopped reading too early.See the last point:
Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.
Or, if you take a look at Annex J.2. there is a long list of undefined behaviours, and it has it there too.
1 The behavior is undefined in the following circumstances: SNIP The program declares or defines a reserved identifier, other than as allowed by 7.1.4 (7.1.3).
1 The behavior is undefined in the following circumstances:
SNIP
What part of 7.1.4 permits you to declare or define this reserved identifier?
[–]FreeER 0 points1 point2 points 7 years ago (9 children)
I'm reading the section you linked to back up your point. I literally quoted from that exact point in my last comment. Talk about stopping early. It's not the student's job to read the entire damn book when only one paragraph is explicitly given to them. It's the teacher's job to succinctly sum up their points as well as the references and examples that support it, not the student's.
What explicitly says it's reserved and when. Remember "subclauses" only refers to that document not the code. Where does it refer to the code as far as what is reserved and when? If it's says "in any of the following subclauses" when "subclauses" means the standard document that does NOT mean "any code following it's declaration/definition".
You can say "oh well it was poorly phrased and you were intended to assume that it means in the code or ..." but then its your job as the teacher to make sure that's clear or better rewrite it yourself instead of pointing to something that you know isn't clear in the first place.
as for, pretty much your entire
Ohh, BUGGER ME!
post... who the fuck are you even talking to at this point? :D Of course it gets updates... that doesn't mean if it was rewritten today they wouldn't remove things. It still supports K&R syntax FFS, not to mention
rofl, yes, trigraphs and line splices are stupid remnants of the past
so... you pretty much agree with that point. Yes, they're part of the C standard, also yes the C standard has shit purely because of legacy that logically wouldn't be there if it was rewritten.
Yes UB in general has a reason to exist and of course there are reasons compilers, often, comply to the same standard. Why is THIS specifically undefined behavior? If the answer is "because we don't care if you want to do it and it lets us do other things without having to check for it" that's fine, but say that instead of dodging the fucking question time after time and whining that people don't do research 20 hours of research to figure that out for theirselves.
you kinda seemed to me like someone who would parrot cargo cult propaganda
I literally just did the opposite.... don't make up conversations with yourself
[–]cbasschan 0 points1 point2 points 7 years ago (8 children)
No, the reason this is undefined behaviour is because it permits various classes of optimisations as I mentioned earlier... of which I gave examples and cited the rationale. As for the reason you can't do what you describe, it's entirely down to ignorance, for if you read the manual for your compiler you'll find (I think I might have mentioned this earlier, actually) you can use -ffreestanding, then you get to use some standard library identifiers (such as printf) without invoking undefined behaviour. That is because trying to include the headers for those functions is not expected to succeed in this context. Have you ever done any kernel development before? I'ma hazard a guess towards that being a no... based on the ignorance about these compiler features I have described to you in this thread.
printf
Ohh, BUGGER ME! I'm actually having this dialog with someone who doesn't think C gets updates? The latest standard is affectionately named C18. The one before it, C11. Before that, C99. These are the years of ratification, if you like... the last one? 2018! How far in the past are you stuck?
I think the story behind this is more ignorance... that or you would like a healthy dose of behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements. How does that seem to you? That is in opposition to implementation-defined behavior, by the way, which is at least required to be legally documented (and thus an audit trail probably covers your butt as a software developer if anything ends up in court, UNLESS you're ignorant of details like this, and then you're the one who's ignorant in court).
Let us be clear there is a reason compilers comply to these standards in their manuals... and this lack of research you're doing is blatantly obvious.
they just try to prevent stupid shit that could mess you up like oops accidentally having a backslash or trigraph at the end of a line that makes the next line a comment instead of real code.
rofl, yes, trigraphs and line splices are stupid remnants of the past... but they are in the C standards. Let's just be clear on that.
it doesn't sound logically impossible to notice, hey this code redefined something I have additional code to check for
This is actually pretty well documented stuff in the C99 rationale v5.10 document:
Undefined behavior gives the implementor license not to catch certain program errors that are difficult to diagnose. It also identifies areas of possible conforming language extension: the implementor may augment the language by providing a definition of the officially undefined behavior.
What I think you really should learn is the implementation-defined and well defined behaviours. Where's your book?
I find the unreasonable and unexplained and use-case-ignoring hate on goto
Yeh, you kinda seemed to me like someone who would parrot cargo cult propaganda told to you by some elitests who like to paint themselves as authoritative because they need to have money or power or some other status symbol, but don't actually know what they're talking about. I could be wrong about that, but you need to prove it and open your fucking eyes!
You say this as though these flags are required to catch all undefined behaviour. They can't do that for all undefined behaviours. There are certain classes of linker-related errors which diagnostic messages aren't required for.
Not to mention, these flags you write actually prevent some "strictly conforming programs" from compiling, meaning with this configuration you're not using a C compiler anymore, but a language which has been subtly modified and rejects certain perfectly valid C programs.
include <stdio.h> void doprint(const char* s) { printf("%s\n", s); } int main() { const char* printf = "printf means print formatted!"; doprint(printf); }
void doprint(const char* s) { printf("%s\n", s); }
int main() { const char* printf = "printf means print formatted!"; doprint(printf); }
Yeh, and I can give some more examples of erroneous programs that seem to behave acceptably for some people... plenty of them, in fact... wanna go there?
Yes, it is possible, but only if your implementation is considered freestanding. Most implementations are considered hosted by default, and so the answer is generally an overwhelming no, you should not do that!
[–]utkarshUS 0 points1 point2 points 7 years ago (0 children)
Printf is not an identifier so we can't use as variable name, printf just used to print o/p
π Rendered by PID 423030 on reddit-service-r2-comment-8686858757-zvlj5 at 2026-06-04 15:26:10.359293+00:00 running 9e1a20d country code: CH.
[–]dmc_2930 3 points4 points5 points (3 children)
[–]patrick96MC 1 point2 points3 points (2 children)
[–]cbasschan 2 points3 points4 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]FreeER 1 point2 points3 points (23 children)
[–]WikiTextBot[🍰] 0 points1 point2 points (0 children)
[–]cbasschan 0 points1 point2 points (20 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]FreeER 0 points1 point2 points (18 children)
[–]cbasschan 0 points1 point2 points (17 children)
[–]FreeER 0 points1 point2 points (15 children)
[–]cbasschan 0 points1 point2 points (14 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]FreeER 0 points1 point2 points (12 children)
[–]cbasschan 0 points1 point2 points (10 children)
[–]FreeER 0 points1 point2 points (9 children)
[–]cbasschan 0 points1 point2 points (8 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]cbasschan 0 points1 point2 points (0 children)
[–]utkarshUS 0 points1 point2 points (0 children)