A look back at original style C

Поделиться
HTML-код
  • Опубликовано: 5 ноя 2024

Комментарии • 151

  • @strayling1
    @strayling1 Год назад +44

    I'm half proud and half ashamed to admit I used preprocessor macros to allow the same source code to compile on both K&R and ANSI. Supporting the same code on about 50 different versions of Unix as well as DOS and other oddities makes you do things like that.

    • @freedosproject
      @freedosproject  Год назад +6

      👍 Using preprocessor macros (like #ifdef) is a powerful way to extend your programs to other systems. Makes it easy in for the same code to compile on Unix using ANSI C and on DOS with K&R C.

    • @J-Random-Luser
      @J-Random-Luser Год назад +8

      I do this, and explicitly port my code to old UNIXes all the time. In my opinion, portable code is better code.
      People have forgotten more and more over time how to support non-mainstream operating systems. Hell, the modern BSDs are probably the most mainstream version of UNIX, and they still struggle to have code written *for* them instead of ported *to* them.
      Don’t get me wrong though, most people, understandably in my eyes, dont have the time, let alone the resources, to port code to these old operations systems. In my eyes, however, I think there is something to be gained in dealing with the limitations of these old platforms that leads to more resilient code.

    • @strayling1
      @strayling1 Год назад +4

      @@J-Random-Luser You nailed it. Porting C to different systems makes learning their differences a must, and is quite an education on how they work at a lower level.

  • @RegisMichelLeclerc
    @RegisMichelLeclerc Год назад +5

    In a fun way, gcc supports K&R style, C++20 and everything in between.
    Fifty years ago, it was UNIX, not Linux (Linux is only 30 years old). Sounds like a detail, but I was learning that version of C on SunOS 4 in 1991 (and OS/9 in 1992), after starting learning C on Turbo-C the year before. I hated C at the time, because I had learnt everything on Turbo Pascal, and it took me a while to get used to it. Turbo Pascal 6.0 was allowing me to write inline assembler without bothering of stack pointers for local variables (you know, the SP/BP headers with RET n at the end because I didn't do the "BOUND" thing at the time, it was 80386 in real mode, etc.), until I discovered pointers on functions and that it was possible to jump to the content of a variable (or a register, like in "jmp [si]"). Being poor at the time, I was very proud of re-inventing lambda, callbacks, functional programming and funky self-modifying data structures (object programming without knowing about OOP, in pure assembly without stack frames). Then only I discovered it had all been done before when someone gave me a book from Alfred Aho, even *my* circular lists, but not my "cobweb lists" (heavily relying on multidirectional "backtracking", I loved playing with local stacks, yes, "push ds/pop ss" is allowed).
    For your program, I used to be explicit with "int main(...)", because I hated warnings. If you start letting go with warnings, it's the open door to really bad errors with pointers and return addresses, forgotten initialisations and so on. It's not so important when it's "just" an int, it becomes a killer and a possible leak when it's an index or a pointer on an int or, worse, when you indirect-call a function. K&R-style is pretty tolerant, therefore you need to never ignore any hint it gives, it saves hours trying to figure where that "core dumped" is coming from. Not even talking about threads...
    Also, the "while() {}" in main() could probably be replaced by a "do{} while()" as you always read the lines and display them in your "if(){} else{}": you're just repeating the fputs for " 1:", making your code longer and not more efficient. Also, although it's probably more human-readable that way, I've always been hunting for functions called only once, especially when the call is in a loop. Function linenum() has no place there, it should be a block in your main loop. By multiplying functions that call each other once, you hide possible optimisations such as fallthroughs (in "case" statements) and shared variables. Yes, even in Java, I rewrite my own String-handling functions so to gain time (ticks) when parsing, and not calling functions saves lots of time and code (especially in Java, where the default strategy is to reallocate and copy the entire string for each character appended, beware of the "str+=chr;" statement). For instance, try writing a JSON parser, that's always a fun exercise.
    As a detail, "66" should be a #define, not a litteral. It's all about the meaning, not the value. If you suddenly need to port your program to European standards ("A4" instead of "Letter"), you'll need to search&replace everything in the program to adapt. If ever 66 is used somewhere else with a different meaning, you're just going to induce bugs. It's unlikely in a 60-line code and "66" is likely to always mean the same thing, but in a 1000 line thing about a graphical boot screen on a cutom OS, a value of, say, "0xc000" may be something catastrophic to mix up -- good luck with debugging that. So, yeah, always use #define, it makes a real difference between SCREEN_START and KERNEL_START and doesn't take a byte more. Changing the value of "#define PAPER_LENGTH" from "66" to "50" becomes meaningful and risk-free. Remember that a symbolic calculator always gives you the right values while a calculator always gives you values approached by default: "0.333" and "1/3" are not the same thing, it makes a very big difference if your goal is to take pictures of Jupiter.

  • @AndrewRoberts11
    @AndrewRoberts11 Год назад +2

    30KB is massive, grab yourself a period compiler, and stdlib and the 16-bit executable will be under 8K.

  • @slonkazoid
    @slonkazoid Год назад +18

    Downloaded and compiled edlin on my linux computer. This is the most relaxing editor I have ever used.

  • @93davve93
    @93davve93 Год назад +1

    I love that it's so clear where the Vim family of editors comes from ❤

    • @freedosproject
      @freedosproject  Год назад +1

      There's a great story in 'Unix: A Memoir and a History' about how Bill Joy showed off his "editor project" when he was visiting Bell Labs. I guess he hung around there a lot. So vi was definitely inspired by the Unix team, not surprising there are some ed influences there.

  • @fragglet
    @fragglet Год назад +133

    If you want to go really crazy, you can define all your local variables using "auto" without specifying the type at all

    • @xravenx24fe
      @xravenx24fe Год назад +60

      no thanks satan lol

    • @freedosproject
      @freedosproject  Год назад +24

      That would be something 😛

    • @kwzu
      @kwzu Год назад +23

      in c if you leave out the type it defaults to int

    • @kreuner11
      @kreuner11 Год назад +1

      Defaults to int

    • @intehelt8606
      @intehelt8606 Год назад +44

      No, that's wrong. That would just make the variables default to int. Typeless variables do not exist in C. What auto does is actually just the opposite to static, and it has no real use case.

  • @tsalVlog
    @tsalVlog Год назад +3

    my first "professional" programming job was maintaining really old C code; I put quotes around "professional", because I had to lie about my age to get the job in the first place.

  • @spearPYN
    @spearPYN Год назад +5

    Classic C on DOS or Linux is always beautiful. Still using command line like its the 80s again...

  • @ahmad-murery
    @ahmad-murery Год назад +21

    It reminded me how I was editing my BASIC programs, we didn't have a fancy editor where we can scroll to the error and we need to list the lines we need to edit.
    Nice video as always,
    Thanks Jim

    • @freedosproject
      @freedosproject  Год назад +4

      Thanks!
      Interestingly, I don't recall using Edlin on DOS at the time .. I think we downloaded some free text editor from a BBS and used that instead. But I really like Gregory's FreeDOS Edlin. I've even compiled it for my Linux machine and I use it there sometimes.

    • @OpenGL4ever
      @OpenGL4ever Год назад +3

      EDITOR.EXE from DR-DOS was much better than EDLIN. Microsoft was only able to eliminate this disadvantage in MS-DOS 5.0 with the new EDIT editor.
      I wrote my BASIC programs btw. directly in the GW-BASIC interpreter.

    • @rugxulo
      @rugxulo Год назад

      @@OpenGL4ever DR-DOS never had Edlin, IIRC. That may have, in theory, been a disadvantage for simple scripts, but I never needed it. (Having said that, I did find a use for Edlin on FreeDOS and emailed Gregory showing him, just for completeness.) They still included the DOS binaries of Edlin and Debug on my 32-bit Vista laptop.

    • @OpenGL4ever
      @OpenGL4ever Год назад +1

      @@rugxulo I never said that. I sad, that EDITOR was better than EDLIN, nothing more.
      You should add the words "from MS-DOS" after EDLIN in your mind. I assume that goes without saying.
      Back then there was usually nothing better available. You had to use what was there. Extra editors and IDEs did cost money. Some assemblers and compilers came without an IDE and consisted only of the command line commands to assemble and compile your code, some even missed a linker. BTW, there is also no LINK.EXE in FreeDOS.
      So you had to write your code somehow and if you had EDITOR from a DR-DOS installation available it was better than EDLIN. That only changed with EDIT.

    • @rugxulo
      @rugxulo Год назад

      @@OpenGL4ever EDIT from MS-DOS 5 was just QBASIC in disguise. (FreeDOS has linkers, but they aren't named LINK. LINK went away after, what, MS-DOS 4?)

  • @mopar3502001
    @mopar3502001 Год назад +4

    This brings back a lot of memories. The only time I find myself coding in C anymore is when coding firmware for a microcontroller or something along those lines. Now I'm going to have to dig out my old Borland C disks and install the IDE on an old system as a weekend project!

    • @freedosproject
      @freedosproject  Год назад +1

      I loved Borland C on DOS! My first FC compiler on DOS was QuickC but I later moved to Borland.
      You might also try out IA-16 GCC on FreeDOS with the i86 library. This provides a lot of the features from Borland. I also use OpenWatcom on FreeDOS - this does everything Borland could do, but the library is a little different (for example, graphics and console drawing functions). Both are available on the FreeDOS 1.3 install CDs.

  • @xcoder1122
    @xcoder1122 Год назад +18

    Trivia: Edlin was the only editor included in MS-DOS up to version 5.0! Only in 5.0 Microsoft would final add a better editor named "edit" (MS-DOS Editor) and that wasn't really an editor of its own. Internally edit would just call "qbasic /editor", as the QBasic IDE had a decent editor for working on BASIC source files and when called with "/editor" it would just function as a general purpose editor (i.e. not expecting content to be BASIC source code and not offering IDE functionality in the menus like running the code).

    • @davidmartensson273
      @davidmartensson273 Год назад +2

      And even while there was other editors there was one case where edlin where often still used, escape codes.
      Edlin had a built in way to write escape codes for ansi.sys which not so many other editors provided.
      If I remember it was ctrl+V and then [.

    • @freedosproject
      @freedosproject  Год назад +3

      That sounds right. My MS-DOS user manual says when in insert mode, ctrl-v and the next capital letter is recognized as a control character. Like ctrl-v then V enters a literal ctrl-v, and ctrl-v then Z enters a literal ctrl-z. The manual doesn't mention escape codes, but ctrl-v then [ sounds right to me.

    • @R.B.
      @R.B. Год назад

      If you were really mad, GW-Basic would let you create files and directories as an editor, but it didn't stop you just using printable ANSI. This would let you create files and directories which were unlistable in DOS, and I don't remember if it wasn't until some time from Windows 95 to Windows XP where they finally made it possible to see those directories or files and delete them. I think it was 95 where you could see the directory was there, but you couldn't open it. It was a clever way to prevent most people from seeing the content. You could do a similar thing with the backspace control character to have a filename list, but if you backspaced over a character and then had another character to replace it, it was another type of filename which could be seen but couldn't be accessed. You were limited to shorter filenames that way, but protected access from the casual snoop.

    • @davidmartensson273
      @davidmartensson273 Год назад

      @@R.B. And then you used a recursive loop creating a directory, go to it and repeat until you reach max depth, teacher had to ask students for help to clean up ;)

  • @charles-y2z6c
    @charles-y2z6c Год назад +1

    Oh the simplicity of the good old days. It was like seeing a good friend from 30 years ago.

  • @MechaFenris
    @MechaFenris Год назад +7

    I've always preferred ANSI to K&R, just because of the editors I use. :)

  • @pajodato5339
    @pajodato5339 Год назад +1

    Thanks for your videos! I almost never comment on videos, but I really like your input on FreeDOS. I mostly use Ubuntu, but I used DOS in the early 90s on a 386SX with 4 megs.

  • @andydelle4509
    @andydelle4509 Год назад +10

    Back in 1986 when I was writing C for embedded systems using a cross compiler, I used Boreland Sidekick as my editor. It was a TSR so your source code was always a keystroke away.

    • @whyis2plus2
      @whyis2plus2 Год назад

      what is a TSR

    • @andydelle4509
      @andydelle4509 Год назад +1

      @@whyis2plus2"Terminate and Stay Resident" Very basic multitasking. The TSR program was relocated in higher memory.The keyboard interrupt was modified to trap a certain key sequence and execute the TSR program from it's memory location. Of course data in used in the TSR, such as a text document being edited, was also stored in higher memory. For certain applications it worked great. But as there was no hardware oversight by the OS, there could be problems, For example if the primary app sent the printer some special config commands on startup. Then the TRS comes along and wants a generic config, the primary program does not have code to reconfigure the printer upon being called back. The primary program had no knowledge it was placed on hold. But TSR's did still work with the more primitive DOS programs of that time.

  • @suvetar
    @suvetar Год назад +1

    Fond memories there! Although by the end of my DOS programming days, the ubiquitous Blue, Yellow and Magenta (always used that for keywords) of Borland TC++3.1!
    Anyway, I know you're likely working from a script, but I'd still like to congratulate you on your presentation skills and keeping it interesting!
    Thanks for sharing!

    • @freedosproject
      @freedosproject  Год назад

      Thanks! I usually use a script for the intro, but after that I do it "as live." So I'm not using a script after the first minute or so. But I do a lot of conference talks, and my consulting business is training and workshops, so I like to think I'm used to talking "live" to an audience.

  • @Silanael
    @Silanael Год назад +1

    I'm a bit younger than that, having only used DJGPP with RHIDE back in the days :)

  • @henriksundt7148
    @henriksundt7148 Год назад +16

    2:45 This should be written "char **argv;" with space after the type name, because the pointer declarator (star) applies to the variables it adhers to, like in char *a, *b, c, d; And it's true to the K&R syntax.

    • @fragglet
      @fragglet Год назад +8

      I know plenty of engineers who write the * next to the type rather than the name because doing so makes it conceptually clearer to them. It's one part of C's syntax that I personally think is a mistake because people find it confusing. Personally I put the * next to the name though because I don't want to "pretend" the syntax is what I think it ought to be rather than what it actually is.

    • @sirgouki6207
      @sirgouki6207 Год назад +1

      that is ISO standard C. Pre-standardized C, it could go either way, and a lot of C books point the pointer operation to the right of the type, instead of to the left of the variable name. A good compiler isn't going to care, because it will ignore the whitespace... you can literally do "char ** argv;" and it should still compile the same way.

    • @nmosfet5797
      @nmosfet5797 Год назад +2

      @@sirgouki6207 Not true if you declare more than one variable at the line.
      int* p, q; -- you would expect that both p and q are pointers, but only p is.
      int *p, *q; -- will declare both p and q as pointers to an integer.
      In C philosophy you as the programmer are expected to keep in mind and state explicitly what is a pointer and what is not, instead on relying on a kind of a type system that plain C does not have.

    • @lainwired3946
      @lainwired3946 Год назад

      ​@@nmosfet5797thats true but tbf in the video each new var gets its own line

  • @C1rnobyl
    @C1rnobyl Год назад

    Amazing looking back at things done before I was even born.

  • @ka9dgx
    @ka9dgx Год назад +4

    I've been avoiding C since the 1980s (I'm a huge TP/Delphi fan), thanks for showing me how the logic of things work. To me, C mostly looks like line noise. ;-)

  • @dingokidneys
    @dingokidneys Год назад +2

    In about 1988, I taught myself K&R C using DOS and a shareware 16 bit smallC compiler, and yes I used edlin. Horrific! I eventually managed to get hold of a vi style shareware editor that improved my life amazingly.

    • @0LoneTech
      @0LoneTech Год назад

      My condolences. I had a far easier time using a book on ANSI C, PC Write, PCC and a TSR file manager named QDisk, iirc. All had their quirks, of course; for instance the file manager could not accept the digit 8 when renaming files.

  • @rugxulo
    @rugxulo Год назад +1

    BTW, the FreeBSD manpage for "nl" says it debuted in SVR2, which Wikipedia says was 1984.

  • @Hiraghm
    @Hiraghm Год назад +5

    Can C programs written with this GCC compiler for FreeDOS run under MSDOS or DRDOS, or are they unique to the FreeDOS OS?

    • @freedosproject
      @freedosproject  Год назад +5

      Yes programs you compile with ia-16 gcc will run on any DOS, including FreeDOS (obviously 😃), MS-DOS, and DR-DOS. You need at least a 386 to run ia-16 gcc, but the programs it generates will run on any computer that runs DOS.

  • @gpietsch
    @gpietsch Год назад +1

    Wow! Edlin and cat in the same video! (The cat program has an option to produce line numbers.) I feel honored...

    • @freedosproject
      @freedosproject  Год назад

      Hi Gregory! 👋
      I have another edlin video coming soon, about compiling edlin from source.
      But I should do more programming videos using edlin .. maybe I'll do a programming video using edlin on my Linux box? 🤔 There's a video I want to do about cross platform programming (DOS + Linux) that might make a good fit for that. 😊

  • @CathrineMacNiel
    @CathrineMacNiel Год назад

    Oh my, edlin looks so relaxing.

  • @rugxulo
    @rugxulo Год назад +8

    BTW, the 'g' in Kernighan is silent. (He only helped write the book. The language was all Ritchie.)
    K&R C (the book) was from 1978. AFAIK, no "const", no "void", no prototypes, no structured return types, "unsigned int" was the only unsigned type, variadic functions needed to be done in assembly, and structure member names were like global variables and thus needed to be distinct. Oh, and the preprocessor couldn't concatenate args properly.

    • @ScottHess
      @ScottHess Год назад +1

      I thought variadic functions was just implemented in terms of pointer arithmetic relative to an anchor variable on the stack, on most platforms. Since nothing in the system enforced caller/callee matching on parameters, you just did whatever you wanted on the implementation to trawl through the stack.

    • @rugxulo
      @rugxulo Год назад

      @@ScottHess Actually, on some platforms, I forget the details, but it's allowed to change the whatever (calling convention, ABI, whatever) on variadic functions. So, at least with ANSI, you *have* to include the right header to use them. Sorry, I don't know the exact terminology.

    • @ScottHess
      @ScottHess Год назад

      @@rugxulo Indeed, because platforms can pass things off-stack, such as in floating-point registers. I have no idea how things worked with SPARC register windows. But even there, before things were standardized most platforms just used a bunch of heuristics to find the parameters. Though maybe I misremember the specifics of the varargs macros - my first C course used original K&R, but the ANSI version of K&R came out like a semester later. Good times!

  • @GilbertLaurel
    @GilbertLaurel Год назад +3

    Nice!, please do more DOS C programming videos

    • @freedosproject
      @freedosproject  Год назад +2

      Will do! I will likely do some games and apps coming up, but I'll get back to more programming.

  • @Mid.G.
    @Mid.G. Год назад +3

    Bro has nice IDE

  • @AK-vx4dy
    @AK-vx4dy Год назад +1

    In my young enviroment i had none to infect me with C, i was infected with Pascal, exactly Turbo/Borland Pascal,
    i became so proficient and this flavour of Pascal was so powerful that i see no advantage in using C (i could always inline assembly ), but in following years i absorbed some knowledge of C (i even write some CGI page with simple "database" funcionality in times about php 3 - but i don't know it existed)...
    Many years ago when i saw this font last time... sweet memories ;)

    • @RandyLea
      @RandyLea Год назад

      Turbo Pascal was so fast and easy, I used it for everything except where I needed assembler. I had tools I wrote to make that easy, I recall the assembler had to be in hex format. Almost everything I wrote was a small utility that didn't require C.

    • @AK-vx4dy
      @AK-vx4dy Год назад

      @@RandyLea i don't know in wich version it came, but about 5.5 or 6.0 you could write assembly inside pascal without external assembler

  • @banzooiebooie
    @banzooiebooie Год назад +11

    This goes disturbingly far into xkcd:378. I am happy with my ultra complex and powerful Java IDE which also puts the curly bracers on the same line as the function. Curly bracers on a separate line is barbaric ;-)

    • @chri-k
      @chri-k Год назад

      no

    • @CPSPD
      @CPSPD Год назад +2

      in c/c++ i really like curly braces on a separate line on the 0th indentation level (so functions, classes etc), curly braces on the same line in everything else (if/else statements, while loops). but im not gonna lie, separate line in java sounds really annoying so i see where youre coming from lol.

  • @brucetungsten5714
    @brucetungsten5714 Год назад

    Very nice!

  • @NotNoAndrew
    @NotNoAndrew Год назад

    Thanks Jim, very interesting.

  • @geekgee
    @geekgee Год назад

    Hadn't thought of edlin in many years.

  • @donwald3436
    @donwald3436 Год назад

    So bizarre, never seen this syntax. I have K&R sitting on my shelf but sure enough, it's the ANSI C edition.

  • @DanelonNicolas
    @DanelonNicolas Год назад

    it was amazing 🎉

  • @stargazer7644
    @stargazer7644 Год назад +6

    "Original style C". Or as we like to call it, "C".

    • @chri-k
      @chri-k Год назад +3

      … but that’ just not true

    • @stargazer7644
      @stargazer7644 Год назад

      @@chri-k Just because the only C you've ever seen might be ANSI C, doesn't make the earlier flavors any less C.

    • @SENTRY456123
      @SENTRY456123 Год назад +2

      You must be calling yourself "Galaxy brain divine intellectual godlike gigachad ancient C programmer" and making fun of other "toy" programming languages like ANSI C.

    • @stargazer7644
      @stargazer7644 Год назад

      @@SENTRY456123 I tried putting this through Google translate, but it couldn't identify the language either.

    • @chri-k
      @chri-k Год назад

      @@stargazer7644 yes, it’s not any less C. Specifically, it’s original C.

  • @BritishBeachcomber
    @BritishBeachcomber Год назад

    I've not used edlin since the 80s but I could edit code, fingers flying all over the keyboard, as fast as with a mouse. Maybe faster.

  • @travisporco
    @travisporco Год назад

    reminds me of @med on the old univac 1100 machine I learned coding on...giving me ptsd watching :)

  • @sparky4insano
    @sparky4insano Год назад

    keep it retro!
    keep it cool!

  • @wherami
    @wherami Год назад

    Learning c now is key

    • @freedosproject
      @freedosproject  Год назад +1

      I agree! 👍 And despite a few things that are necessarily close to the hardware (memory allocation) I think C is a pretty easy programming lanugage to learn.

  • @yuyuyuyuyuy484
    @yuyuyuyuyuy484 Год назад +1

    My short attention span would definitely not allow me to work with that editor lol

    • @gdtyra
      @gdtyra Год назад

      Yea, I thought I was hardcore as a vim user but...

  • @anon_y_mousse
    @anon_y_mousse Год назад +6

    You're braver than I. Personally, I can't stand K&R style, especially bracing. Allman style bracing for me for life. Towards that end, do you have a cross compiler that you can use to compile C23 code for 16-bit x86 platforms?

    • @MH_VOID
      @MH_VOID Год назад +1

      I'm the opposite. I hate allman-style, and use something much more like K&R (and wouldn't have much of a problem just using plain ol' K&R). I'd take allman-style over being forced to use soft tabs, though.
      for me, something like this:
      ```
      fn foo(a, b) {
      bar;
      baz;
      }
      fn whatever(a, b) { single_simple_statement }
      fn bar(ooga, booga, nstarooga) {
      whatever
      }
      foo(simple_arg_0, simple_arg_1);
      foo(
      simple,
      simple,
      simple
      )
      foo(
      simple_arg,
      an_arg_that_is_not_simple
      );
      bar = { thingie, another_thingie };
      bar = {
      thingie,
      thingie,
      longer_thingie
      }
      if cond_0 {
      thing_0;
      thing_1;
      } else if cond_1 {
      whatever;
      } else {
      whatever;
      }
      if cond_2
      && cond_3 {
      whatever;
      } else if cond_4 { single_statement }
      foo.bar().baz();
      foo
      .bar()
      .baz()
      .qaf();
      foo.bar(a, b,c).baz();
      foo.bar(
      long_arg,
      whatever
      ).baz();
      foo.bar(
      long_arg,
      whatever
      ).baz(a, b);
      foo.bar(
      whatever,
      thingie(
      a,
      b,
      c
      )
      )
      .baz();
      ```
      Not quite correct but good enough to get an idea.
      When mentally parsing you have to look forward up to one non-space non-tab character, or a space followed by a non-space non-tab character, before advancing to the next line. Likewise, when at the next line, start by looking for either a non-space non-tab character, or one tab plus a non-space non-tab character, before or at the previous line's indentation level.

    • @anon_y_mousse
      @anon_y_mousse Год назад +1

      @@MH_VOID Interesting, because I use Allman style and soft tabs, set to insert four and I use two for each indentation level. I don't like auto-insert, for various reasons, so I manually hit the tab key for every two depth levels and space for the odds. I also don't use braces when I have a single statement inside a conditional block, and I hate the multiple levels of dot functions, whether it's part of a class or attached.

    • @OpenGL4ever
      @OpenGL4ever Год назад +2

      @@MH_VOIDI don't use tabs at all. I learned from my professor at university that using tabs is bad coding practice. Indentation is done with only 2 blanks.
      That's how I do it with my C code.
      But what I personally don't like are missing curly brackets in an If statement with only one statement. It's allowed by the standard, but I don't like it. That's why I always use curly brackets.
      The risk of overlooking something or adding something later and then forgetting the brackets is just too great. If they're already there, then they're there, and if you get into the habit of always setting them, then you don't forgot them.

    • @MH_VOID
      @MH_VOID Год назад

      ​@@anon_y_mousse You, sir|ma'am, are a barbarian. Begone!
      If you have it set to insert 4 and use 2 per indent level, why not just have it insert 8?
      Auto-insert and other "smart behavior" can definitely be annoying. I frequently use stuff with both smart and dumb behavior - I'm composing this message right now in Nano, and do my development in either Emacs or Nano depending on if I'm just making a quick change or not. Nano is pretty much completely dumb, emacs has some nice auto-insert functionality. It's fairly easy for me to switch between the two - I only enabled the smart behavior in emacs because it saves time and energy not having to do the like, "enter backspace closing parens enter continue" motions i have to do otherwise. Sometimes I really do just want to turn it off though and just embrace the simplistic caveman. And the number one thing about all that smart behavior is that it has to be dependable - I should be damn sure that it will indeed insert what I am expecting and not even need to look at the screen to have that input.
      One of the nice things about tabs is that it's far more agnostic of how smart the editor is, of how many characters it'd delete when pressing backspace or when hitting enter. Spaces might be some random number especially if you use something abnormal like 3 or 6 spaces per indent level. You're never going to have to press backspace 10+ times like you easily could when dealing with spaces. Far less frustrating. There's honestly almost 0 benefits to using spaces over tabs, whereas there are a plethora of benefits to using tabs over spaces.
      I mostly program in Rust (most everything else is ZSH), which mandates the cbraces around the body rather than mandating the parens around the condition (a far, FAR more sensible approach IMHO). However in C or similar, I'd do
      ```
      if (fubar) { return 1 }
      for (int i = 0; i < 42; ++i) {
      thing;
      more_things;
      }
      for (int i = 0; i < 42; ++i) { single_thing }
      ```
      perhaps if I was feeling very lazy I'd omit the braces.
      in Rust, where everything is an expression, I frequently do
      ```
      let foo = if bar {baz} else {0};
      ```
      where the spaces are omitted when it's just returning a single simple thing.
      I'm not quite sure what you're trying to say regarding multiple levels of dot functions. I personally am a huge fan and (ab)user of iterators, streaming, method chaining, immense command-substitution-heavy shell pipelines, and all that jazz, though.

    • @MH_VOID
      @MH_VOID Год назад +2

      @@OpenGL4ever It's not that using tabs is bad coding practice: it's that using tabs for alignment is bad coding practice which defeats much of why people use tabs in the first place, and that many people that use tabs for indentation erroneously use them for alignment as well. Tabs for indentation; spaces for alignment. That's how it should be.
      I agree with the missing curly brackets in an if statement with only one statement. C and similar allow it, but it definitely leads to bugs. When using those languages, I try not to do it, but sometimes I'm really really lazy and just do it for the time being, accepting the future risk. The way Rust has it is just straight-up better, as far as I know. Hopefully all languages eventually have to mandatory braces, optional parens, too.
      Vulkan > OpenGL

  • @MatthewDeVore
    @MatthewDeVore Год назад

    9:00 in my K & R book and Linux man pages, FILE* is documented as being buffered, and even getc is a possibly-macro version of fgetc, which suggests that it's equivalent to indexing into an array, while fgetc just has a function call overhead. So I don't believe your use of fgetc to read an entire file is slow.

    • @freedosproject
      @freedosproject  Год назад +1

      Reading one character at a time to do something like reading a file and printing it out (basically a "copy" from a file to stdout) isn't a bad method, but you can get much better performance if you read the file by parts, using fread() and fwrite(). I'm planning an article for Opensource.net about different ways to do that, including performance. Not a big difference on a fast system, but much more noticeable on slower hardware (or if you boot a virtual system that *doesn't* use KVM acceleration).
      On a VM without KVM acceleration (to slow it down) this is how long it takes to copy the /usr/share/dict/words file to a new file using different methods:
      /bin/cp: 0.04 secs
      fread/fwrite: 0.05 secs
      readline: 0.34 secs
      fgetc/fputc: 1.26 secs

    • @MatthewDeVore
      @MatthewDeVore Год назад

      ​@@freedosproject I get a 50% speedup using fread/fwrite vs. getc/putc. I believe this is because gcc is not inlining getc and putc in my compilation, and less significantly because it is converting my byte-per-byte buffer copy to a memcpy.
      I did not use a special VM, just ran the operation in a shell loop 500 times on the dict file.
      If you do an strace on your fread and fgetc implementations, you will see the same scale of read and write syscalls being executed. For me, the number of calls was identical +/- 1. fread and fgetc used the same 4096 byte buffer implicitly.
      It is misleading to say fgetc/fputc are reading/writing a single byte at a time. It is more a mechanism of the compiler not being able to inline the implementation, because GNU libc supplies getc/putc as normal functions. If you had a C library implementation which exported the FILE* layout in the header and implemented getc/putc as macros--as the C standard nudges it to do--the difference should be much less pronounced.
      Your conclusion that fread/fwrite are better to use for performance's sake is correct. Calling the read/write syscalls is also permissible, and even obviates the dummy buffer you are forced to introduce for fread/fwrite. I am interested in what the moral equivalent of that would be in DOS C code.

  • @MsDuketown
    @MsDuketown 8 месяцев назад

    The parser dictates the commands.
    See *bsd* command set.
    Also,
    * In 1973, in a key pioneering approach, Unix was rewritten entirely from assembly language into the C programming language by Dennis Ritchie (except for some hardware and I/O routines).;
    * ANSI C is from 1987;
    * Linux was released 17 September 1991.
    About the Comment Style:
    Use either the // or /* */ syntax, as long as you are consistent.
    Personally, I like using # or // for single lines and the /* */ syntax for multi line comments. But the latter should be avoided.

  • @guilherme5094
    @guilherme5094 Год назад

    👍!

  • @foobarf8766
    @foobarf8766 Год назад

    Be curious to see the modulo version! Thanks

    • @freedosproject
      @freedosproject  Год назад +2

      You'd need to change only a few lines (because of how I wrote it) but basically it's
      line = ++line % 66;
      That increments the line count, and uses modulo so the number stays 0 to 65.
      But if you're on a really really slow system, you might reconsider if doing addition and modulo for every loop is faster or slower than doing an increment and "equal" compare every loop, followed by a reset once every 66 loops.
      [edit: typo]

    • @sourestcake
      @sourestcake Год назад +1

      ​@@freedosproject Just be careful to not write line = line++, otherwise you'll certainly run into undefined behaviour.

    • @freedosproject
      @freedosproject  Год назад +1

      Yes, it would be safer (and clearer) to write:
      line = (line+1)%66;
      Keeping it simple is important for the day when future-you has to debug it. 😅

    • @sourestcake
      @sourestcake Год назад

      @@freedosproject If you're using a recent compiler and have the right libraries, you can also enable -fsanitize=undefined to catch undefined behaviour when it slips by. Recently i ran into (x

    • @0LoneTech
      @0LoneTech Год назад

      ​@@sourestcakeI stumbled upon that as a bug in MicroPython for ESP32. It broke half the interrupts, which was also surprising. Happily Pycom took the fix (1ull

  • @RandyLea
    @RandyLea Год назад

    Recently, the channel had a video on installing FreeDOS in QEMU on Linux. I want to run FreeDOS on WIndows 11 in QEMU, has anyone written or done a video on that? Also, what is the best way to move apps/data into the QEMU virtual disk?

    • @freedosproject
      @freedosproject  Год назад

      The basic steps to install FreeDOS using qemu on Windows should be the same as using qemu on Linux.
      Not sure what Windows tools to use to transfer files between Windows and a qemu guest though .. I use guestfstools on Linux which makes it really easy. I can also access the qemu virtual disk directly from gnome on Linux, so maybe Windows can do the same?

    • @RandyLea
      @RandyLea Год назад

      @@freedosproject I appreciate the help, I know your not the qemu support person. I did get freedos running on Windows 11 fine. I saw a video on adding a virtual drive on Linux that allows me to send files back and forth, but I need to adjust the command to get it running on Windows (if it works). Otherwise, I might try to send the img file over to my Ras Pi and add all the programs I need there, then send it back to Windows. Thanks

    • @RandyLea
      @RandyLea Год назад

      One of the apps I want to run is the Small C compiler from DDJ magazine. Its a useful subset of C, but has full source available, lots of text processing tools (with source), and a complete book and lots of DDJ magazine articles available. Its limited, but has enough to be self-hosting.

    • @RandyLea
      @RandyLea Год назад

      Sometimes we just blindly get lucky. From the video on adding a virtual drive to Linux, I added the command "-drive file=fat:rw:dosfiles\", adjusting the "\" for Windows. I was expecting to see a folder in FreeDOS, but it literally is the D: drive. I need to check on the sound and to see if there is a way to get the emulation faster, but it seems to run fine. The other alternative I thought of to move apps into FreeDOS is to just put everything in an iso file and mount it.

    • @freedosproject
      @freedosproject  Год назад

      @@RandyLea Glad you found that option! I always forget about that one - for the work I do in qemu, I found that mapping a host folder to a guest drive worked okay, but *sometimes* could cause problems (but then again, I'm probably not the typical use of that feature because of the things I do there😃).

  • @FredBakker
    @FredBakker Год назад +1

    But by far the biggest issue with this video is the wrong curly bracket style😅

  • @sirgouki6207
    @sirgouki6207 Год назад

    What's with the mixed styles? Is there a reason or could you just not decide on one?

    • @freedosproject
      @freedosproject  Год назад

      The main purpose was to write the program using original K&R declarations like:
      main(argc,argv)
      int argc;
      char** argv;
      { …
      }
      If you mean the "mixed" style where I don't "inline" my "else" with the preceding } and following { like in the book, that's my personal preference. But it's a minor deviation so I didn't call it out.

  • @nomadhgnis9425
    @nomadhgnis9425 Год назад +1

    can you tell me if there are any freeware bible programs (king james bible) that is free to distribute without any licensing issues. I want to have a backup of this for future use. if you have a 1.44 mb floppy image with it already preinstalled then that would be wonderful. if you can do a video on this that would be nice. thanks.

    • @freedosproject
      @freedosproject  Год назад +1

      There were lots of bible study programs written for DOS. You can usually find these on DOS software archive sites. Some may have been released as freeware.

    • @nomadhgnis9425
      @nomadhgnis9425 Год назад

      @@freedosproject i tried searching but I cannot find any. can you recommend some.

  • @Colaholiker
    @Colaholiker Год назад

    Okay, it is bad enough that I have to work with a compiler that doesn't even fully understand C99 at work. But this is a new level of awful - I am glad I never had to deal with that ancient of a C dialect. 🤣

    • @0LoneTech
      @0LoneTech Год назад

      This isn't the awful bit. I've dealt with an intentionally crippled compiler (Knudsen) that didn't agree with its own documentation. Then there were vendor shipped "cc" scripts, which would advertise the not included compiler and not indicate error. This is why autoconf checks your compiler can generate executables.

  • @ronan1690
    @ronan1690 Год назад

    do you know the name of the font by any chance? (or could you please check that?)

    • @freedosproject
      @freedosproject  Год назад +2

      This is just DOS in character mode. I'm not usin g a special "font" here. If you want to use a font like this (such as in your editor) you can download one of the aspect corrected VGA fonts from int10h.org/oldschool-pc-fonts/ - you probably want IBM VGA 8x16 aspect corrected.

    • @ronan1690
      @ronan1690 Год назад

      ​@@freedosproject tysm

  • @kamertonaudiophileplayer847
    @kamertonaudiophileplayer847 Год назад

    Where is NULL defined? You should use just 0 for that.

    • @freedosproject
      @freedosproject  Год назад +1

      Good catch for original style C, I should have done that instead. ☺

  • @WayneOliver-The
    @WayneOliver-The Год назад

    A simpler time :(

  • @fishypugbruh
    @fishypugbruh Год назад

    I thought this was an ARG

  • @davidlloyd1526
    @davidlloyd1526 Год назад

    I need to research when NULL became a thing in stdlib, because I think it wasn't there originally. You had to use 0. That's just too geeky, maybe I'll stop!

    • @0LoneTech
      @0LoneTech Год назад

      True, and the standard still specifies that 0 as a pointer translates to NULL, whatever bit pattern it is (not necessarily zero). My tattered book on C89/C90 (ISBN 1-55615-359-7) defines NULL as a macro expanding to 0, 0L or (void *)0, made available by all of locale.h, stddef.h, stdio.h, stdlib.h, string.h, time.h.

  • @godnyx117
    @godnyx117 Год назад

    Good old ugly C!
    If you are to write small libraries and algorithms, and maaaybe some small apps, then C shines! If you are to write software or any small to medium level app, then fuck no!
    Even in the first case, you could use D and you would have all the benefits of C and a better language.
    And I'm developing Nemesis to slay them both (along side any other programming language in the world). But until then, D is the currently best option!