How to Write Function-Like Preprocessor Macros (C example)

Поделиться
HTML-код
  • Опубликовано: 7 июн 2024
  • Patreon ➤ / jacobsorber
    Courses ➤ jacobsorber.thinkific.com
    Website ➤ www.jacobsorber.com
    ---
    How to Write Function-Like Preprocessor Macros (C example) // In case you've used #define to create program constants, but want to take your C or C++ preprocessor knowledge to the next level, this video takes a look at function-like macros, some of their strengths and weaknesses, and how to address some common macro problems.
    ***
    Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
    About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
    More about me and what I do:
    www.jacobsorber.com
    people.cs.clemson.edu/~jsorber/
    persist.cs.clemson.edu/
    To Support the Channel:
    + like, subscribe, spread the word
    + contribute via Patreon --- [ / jacobsorber ]
    Source code is also available to Patreon supporters. --- [jsorber-youtube-source.heroku...]

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

  • @JacobSorber
    @JacobSorber  2 года назад +76

    In case, anyone else is wondering. You can generate preprocessed C code using the "-E" option in gcc and clang.

    • @AyushSharma-ny8bm
      @AyushSharma-ny8bm 2 года назад +2

      Hi Jacob, I humbly insist you to make a GTK (GUI framework) setup and getting started video. Especially for "How to work with GTK and Makefile?"
      PS: I have a project to make using GTK, need help! I'm not even able to set it up and build the project using Makefile.

    • @AyushSharma-ny8bm
      @AyushSharma-ny8bm 2 года назад

      @Rishab Tirupathi Thank you brother!🤗

  • @Neffins
    @Neffins 2 года назад +18

    I feel like the answer to "let me know if you want to know more about X" is always yes Jacob, thank you.

  • @XenoTravis
    @XenoTravis 2 года назад +19

    This deserved a bit more on the different features the preprocessor has to be considered a deep dive. I would be interested in more on this topic before making a compound video.

  • @nomadic-insomniac
    @nomadic-insomniac 2 года назад +19

    Part 2 , variadic macros, stringizing ?
    My favourite example being
    #define LOG(fmt, ...) printf(fmt"
    ", ##__VA_ARGS__);
    Was mighty proud of myself when I figured how to use them :)
    One of my mentors once told me never to put functions into macros, you may get away with it once or twice but you will eventually fail, use inline functions instead.

    • @nallid7357
      @nallid7357 2 года назад +2

      Your mentor also forgot to mention that modern compilers are smart enough to inline functions themselves rather than using the hint keyword 'inline'. Unless you're using old compilers, the mention of inlining functions is redundant (sometimes detrimental) to the compiler. Only in special cases do you ever use the keyword inline.

    • @saulaxel
      @saulaxel 2 года назад +1

      @@nallid7357 You rarely talk about inlining without mentioning the inline keyword. I think that mentioning it, albeit mostly useless, is a good excluse to talk about these kinds of optimizations.

  • @sallavatsal
    @sallavatsal 2 года назад +2

    This is a very good way of explaining Macros! In fact, I've not seen anyone explain it in a language simpler than this. Because of this video, I will now be using typeof operator which I never understood before. Thanks Jacob!

  • @FintasticMan
    @FintasticMan 2 года назад +13

    Do be aware that the typeof used in the last section is actually a GNU extension, and not officially part of the C specification. There is a possibility however that it might make it's way into C23 though.

    • @Vlad-1986
      @Vlad-1986 9 месяцев назад +2

      That's cool! Sadly, most of my C programming is done under DOS with C89, so not going to see much usage of it. That can explain why I never heard of it

  • @berk473
    @berk473 2 года назад

    I love your videos!! Please keep making them👍🏽

  • @shaharslan3372
    @shaharslan3372 2 года назад +1

    Now this what I call great teaching!

  • @zakagg4707
    @zakagg4707 2 года назад

    Many thanks, realy one of my best Chanel and yes we definitely want to see more about macros.

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

    Great explanation and examples!

  • @shrutichavan2398
    @shrutichavan2398 2 года назад +1

    Thank you so much for this detailed explanation, that's exactly what I was looking for today!

    • @JacobSorber
      @JacobSorber  2 года назад

      You're welcome. Glad it was helpful.

  • @alihanouch8028
    @alihanouch8028 6 месяцев назад

    The best coding professor ever you got the best pedagogy so far.

  • @shuaiqingluo3544
    @shuaiqingluo3544 2 года назад +3

    Thanks for the great video! One quick question: why using the compound statement with declaring local variables solved the problem?

  • @_veikkomies
    @_veikkomies 2 года назад +2

    Definitely make a compound expression video!

  • @deepakr8261
    @deepakr8261 2 года назад +23

    Another interesting thing I learned from multiline macros is the advantage of using do/while(0) block for multiline macros over scoped usage(the compound multiline macro demonstrated by Jacob). Consider the below eg:
    #define CALL_FUNC do { /
    Do some stuff; /
    Call func() ;/
    }while (0)
    Usage in code:
    if (condition x)
    CALL_FUNC;
    else
    printf("Condition failed!");
    If CALL_FUNC was a scoped block (ie without do/while(0)), the semi-colon at the end of macro usage CALL_FUNC would terminate the if block causing compilation error due to the now zombied 'else' block. The do/while(0) safely circumvents this and thus has been a more preferred way to do multiline macros for me as it can now be used everywhere.

    • @saulaxel
      @saulaxel 2 года назад +6

      Not exactly in this case. Take a look at the parenthesis around {}. When there is a ({ something }), it is, something surrounded by both parenthesis and brackets, it is a statement expressions, which is a gcc non-standard extension that behaves like a normal expression instead of behaving like a block statement; hence, it worls well with your example. This arguably has the benefits of using do{}while(0) but with a cleaner (maybe?) syntax.
      In this case, the drawback is that this is not portable, not that it fails in your example

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

      A do while is an statement, not an expression.
      Therefor it can not used in the example of the video.
      That code "returns" a value from the macro, and must be an expression.
      A do while does not have/return a value.

  • @anon_y_mousse
    @anon_y_mousse 2 года назад +1

    Even though it's `gcc` specific, this is a pretty good start for teaching about the preprocessor. I personally wish they'd just include a lot of C++'s more basic features in C, such as templates and function overloading and especially operator overloading. For a few years I did some development on Windows and I used Lcc-Win32. The guy that wrote it, started with just porting `lcc` to Windows, but he added a lot of awesome features while he was at it, such as operator overloading. He implemented a fairly complete IDE with a resource editor. If you ever do any Windows development, might be worth a shot.

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

    Best macro video so far. It would be great to make another macro video but this time debunking some of those crazy macros that we see for instance in opengl/glew header files. Nothing like a real case scenario.

  • @sghsghdk
    @sghsghdk 2 года назад +3

    Remeber to do it like this "do{ statements; } while(0)". That way ending semicolons are enforces and syntactically use of the macros works exactly like normal functions.

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

    how does this only has 28k views rn damn, the multi line pre processor macro was insane

  • @ekinigdr2030
    @ekinigdr2030 2 года назад +3

    great video again. I wish you mentioned some handy stuff like paste, stringinize, function name macro helper thingies. Also appearently there is this macro switch statement (maybe its a gcc addon) that works on types so you could write stuff like generic math libraries. Didnt know about compound statements that was kinda cool

    • @XenoTravis
      @XenoTravis 2 года назад +3

      Good point. This video does deserve a bit more on the different features if it is considered a deep dive.

  • @diegonayalazo
    @diegonayalazo 2 года назад

    Thanks

  • @szeryk324
    @szeryk324 2 года назад +2

    Very good video! I've just discovered your channel, you are doing great job man! I've just switched from being high level C++ developer to more low level C / embedded engineering and I find your videos extremely helpful. Thanks 😊

  • @aabdev
    @aabdev 2 года назад +1

    How to calculate some crc function in compile time? It can be handy in order to put some structure in flash( text segment) when address is not determinated ?

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

    @jacob Sorber - Very nice video and very clear. I have some follow on question. 1. Typeof operator. Is it part of standard C? 2. Is it possible to have a video with more issues with macro? Maybe, you can call that video as "pitfalls of macros in C". Please let me know, if you need any help in preparing the content. thanks again.

  • @AyushSharma-ny8bm
    @AyushSharma-ny8bm 2 года назад +2

    Love the video!♥❣🔥
    Thank you, Jacob!
    Learned a completely new thing today!

    • @JacobSorber
      @JacobSorber  2 года назад +1

      You're very welcome. Glad I could help.

    • @AyushSharma-ny8bm
      @AyushSharma-ny8bm 2 года назад +2

      @@JacobSorber Hi Jacob, I humbly insist you to make a GTK (GUI framework) setup and getting started video. Especially for "How to work with GTK and Makefile?"
      PS: I have a project to make using GTK, need help! I'm not even able to set it up and build the project using Makefile.

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

    Could please explain the kinda of macros Check (framework for unit tests in C) uses? I believe they are a bit different

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

    When to use macros for code generation. is there a rule of thumb? Does it actually improve the code?

  • @abhishekupadhyay2641
    @abhishekupadhyay2641 2 года назад +2

    I used to follow every video that you have posted. And simply I love it.
    Can you please start videos on kernels device drivers series?

  • @NunoFidalgo
    @NunoFidalgo 2 года назад

    Your vids are great, kudos

  • @user-ux2kk5vp7m
    @user-ux2kk5vp7m 2 года назад +1

    I never knew that typeof() existed, that’s really cool

    • @user-ux2kk5vp7m
      @user-ux2kk5vp7m 2 года назад

      @@Ricardo-C yeah I found that through some research. Same goes for the compound statement

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

      Pretty sure typeof() is a GNU extension, unless it was picked up by the main standard very recently.

    • @user-ux2kk5vp7m
      @user-ux2kk5vp7m Год назад

      @@r3jjs its an extension added in C23

  • @Thel-foo
    @Thel-foo 7 месяцев назад

    Damn. Thank you! This reminds me of generics.

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

    does anyone knows which kind of extension is he using to have that typography?

  •  2 года назад +6

    I was expecting some cool weirdass macro uses like X macro pattern or variable length / optional arguments, also I think C11's _GENERIC macro func is rly interesting

    •  2 года назад +1

      #/## operators

  • @mandar.vaidya
    @mandar.vaidya Год назад

    can you please create one using ##

  • @virgoash7775
    @virgoash7775 2 года назад +2

    I have a feeling that the 70's generation are the ones who know a lot about programming.

    • @JacobSorber
      @JacobSorber  2 года назад +3

      I'm pretty sure that people who program a lot, and study programming a lot, are the ones who know a lot about programming. 😀

    • @virgoash7775
      @virgoash7775 2 года назад

      @@JacobSorber I agree with you totally, but c programming language is an old language, it's shown in 1972, and programmers still use it until now because c is detailed and perfect in many ways, and it's shown at AT&T bell labs which is a company specializes in telecomunications, so servers are based at unix os which this last is programmed in C.
      I know you know this, but i mentioned 70's generation because they saw the beginning of computer's revolution, and what fetched me about you is you tell this younger generation including me, a generation that is so lazy want everything fast and easy like frameworks, instead of telling us to program with python like a lot do, you get straight to the point. and i watched your video about assembly language is a waste of time (p.s I liked this video a lot), you give me a word of wisdom the real programmer should really know how the computer works under the hood, and assembly is older than C, and as you say is a human readable machine code, which means this is the language that is good for embedded systems, but because C's compiler is made with it, it means that C converts into assembly.
      I'm a beginner but i started programming by reading older books, I see that a lot of functions was removed from this newer compilers, and programming industry is about details, so the learning curve it's not as the same from one generation to other, if you miss the ; in your c source code the computer won't compile the code, this is works for the humans brain as well, if any human didn't understand know that there is something undefined.
      And thank you. For the information that you give us is really helpful.

  • @xCwieCHRISx
    @xCwieCHRISx 2 года назад

    in c++ you could use macros as template functions when the operators are overloaded for the objects u pass in. Im not sure its good practice though.

  • @sanjayteja447
    @sanjayteja447 10 месяцев назад

    how to avoid the problem of unguarded macros when multiple #includes are used?

  • @redcrafterlppa303
    @redcrafterlppa303 2 года назад +1

    Couldn't you replace all constexpr functions with preprocessor functions since they all should be working at compile time?
    PS: Only asking if you could not if you should.

  • @muhammadAli-zv6rx
    @muhammadAli-zv6rx Год назад

    am i wrong , or these doesnt work on visual studio ( MS complier ) ??

  • @jimboy4090
    @jimboy4090 2 года назад +5

    One thing to note also is that we cannot do recursion with macros

  • @homeofjavascript
    @homeofjavascript 2 года назад

    More about compound expression

  • @Awwe12675
    @Awwe12675 2 года назад

    Bro can you help me I need understand two problems thread and fork
    I mean I need implementation own!
    Sorry for my bad English please help

  • @gfsadds5574
    @gfsadds5574 2 года назад

    Good video, is macro just like adding inline before function in C++?

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

    How do you prevent double inclusion for a function macro???

  • @b4ttlemast0r
    @b4ttlemast0r 2 года назад +1

    couldn't you do the same thing with a template function in C++?
    template T min(T a, T b) {
    return a < b ? a : b;
    }

    • @md2perpe
      @md2perpe 2 года назад +1

      Yes, but that's C++ not C.

  • @R4ngeR4pidz
    @R4ngeR4pidz 2 года назад +1

    Any chance you could leave us with the command to output the pre-processed file? sounds like that's pretty crucial to debugging macros

  • @mrjoepietube
    @mrjoepietube 4 месяца назад

    preprocessor has strange behavior with inline asm. #define testfunc(x) asm("mov r0, # x") do'snot work because when used the x is not evaluated and replaced bij the numerber of calling code like testfunc(2);

  • @1deepakbharti
    @1deepakbharti Год назад

    I am using macro to access two functions according to case in header file and its cpp. If macro is defined 1st function will be active and if notdefined then 2nd function. But I am unable to achieve the same.

    • @1deepakbharti
      @1deepakbharti Год назад

      Can you guide me regarding the same?

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

      There's not enough info to know exactly what you're doing, but my guess is that you might be trying to make the preprocessor do more than it can. I would look at the preprocessed code (use the -E option) and it might make more sense what's going on.

  • @MDarkus3
    @MDarkus3 2 года назад

    Why in your example rand() always give same number (despite re-compiling 8:50) ? This looks a strange behavior to me for a random function generator oO

    • @auz7977
      @auz7977 2 года назад +6

      this is because he didn't provide a unique seed to the random number generator by using srand().
      if the generator has the same seed, it will always produce the same sequence of "random" numbers.

  • @LogicEu
    @LogicEu 2 года назад

    Great topic! Another thing to consider when using macros is the expression evaluation and the use of parenthesis!!! For example, if you say MIN(x + 5, y + 5), it would evaluate to (x + 5 < y + 5), which is wrong. This can be solved by defining macros with extra parenthesis ((A) < (B) : (A) ? (B))

  • @suncrafterspielt9479
    @suncrafterspielt9479 2 года назад +2

    I did not get how with the compound expression the printf knows what to print... I mean, how does it know to print the result of the ternary operator and not from the variable declaration?
    ...Is my question even understandable? :o

    • @homelikebrick42
      @homelikebrick42 2 года назад

      Printf gets the passed as an argument the result of the ternery operator

    • @suncrafterspielt9479
      @suncrafterspielt9479 2 года назад

      As far as I understand it "n3 = MIN(n1 = getnum(), n2 = getnum());" will be replaced by
      "n3 = ({
      int _a = (n1 = getnum());
      int _b = (n2 = getnum());
      _a < _b ? _a : _b;
      });"
      but where is the assignment to n3? What would happen if I write
      "n3 = {
      1

  • @harikrishnanb7273
    @harikrishnanb7273 2 года назад +2

    Rust vs C ? what are the differences? Why rust is most loved? Is it really better than C or not ?

    • @nunyobiznez875
      @nunyobiznez875 2 года назад +1

      Honestly, Rust is "most loved" because it's the shiny new toy, IMO. Better for what exactly? What's "better" is highly subjective, and varies from one situation to the next. Both languages give you the raw tools to accomplish whatever you want to do. It also really depends what you are trying to do or what you want to use it for. If you want to do systems programming on Linux or another Unix-like system, C is better. For embedded systems, C is better. If you are talking about for a Windows desktop App, then rust may be a better choice for your situation, as it has object oriented features. If you're a sloppy programmer or if you need features to help ensure an app is secure, then rust may be better, since it also has features that will protect you from yourself, which helps to enforce security and type safety. Although, it's certainly possible to write robust and secure C code as well, and many do, there's just no one looking over your shoulder to enforce it. C gives a lot more freedom, it makes the assumption the programmer knows what they're doing, and tries to stay out of their way. I appreciate the freedom C provides, but that also means you have more freedom to make mistakes as well. Though, that will also force you to learn more as well.
      If you're writing an app for the control rods at a nuclear power plant or the landing struts on an aircraft, perhaps C may not the best choice. Although both rust and C++ are sold as being systems programming languages, there has yet to be a kernel in either, and C is generally the language of choice for systems programming. Nearly every OS has primarily used C under the hood, even Windows. To be fair, rust hasn't been around that long though, but I doubt that would change anything. If you want to know which is better for learning though, I'd say C is much better to start with, because it's easier to learn and will help you learn how things work under the hood and why they work the way they do, and would probably make learning rust much easier afterward. C is a lightweight language, with fast compile time and performance. Although there are a LOT more C libraries, it doesn't have as many convenience features in the language itself, as many higher level languages do. That's great for learning, and great if you love programming, but not always the best if you just want to write something as quickly as possible. C's syntax is terse and elegant, though it's more of a do it yourself language. It's is a fairly easy language to learn and can be learned fully in just a couple of months, though it's more difficult than that to really master.
      Rust is a higher level language than C, it has more built-in safety and security features, and includes more tools that make "getting the job done" easier, like an online package manager, concurrency, security, safety and object oriented features, but all of that also adds overhead, increases the complexity of the language and the syntax, makes it a bit more restrictive, verbose, and tends to make it more difficult for beginners as well, since there's more to learn. If you believe more is always better though, then you might prefer rust. If you study the Unix Philosophy, or are accustomed to a Unix environment though, you'll appreciate the value of simplistic design, and you'll know that more is definitely not always better. I also personally dislike some of rust's syntax as well, so I haven't used it much myself. That may partially be a preference thing, but probably not completely, as I've heard similar criticism from others. But that's something you'd really probably need to judge for yourself. Hopefully I don't sound overly negative about rust, because that's not the intent. You asked if it is really "better" than C though, so I assume you've already heard the song of rust sung by it's promoters, about it being all sunshine, roses, and unicorn farts.
      The best advice I can give you though, is to read as much as you can about both from reliable, objective sources. Then learn both C and rust for yourself, in whichever order you choose, and decide for yourself which one you think is better, for whatever purpose you wish to use them for. In my experience, that's the only way you will ever really know which one is better for you, for any given task. Otherwise, you'll just keep getting different opinions, that won't really give you a feel for either language, from different people, who have very different needs, goals, and preferences than your own.

  • @batuhanbatuhan6445
    @batuhanbatuhan6445 2 года назад

    why is getnextnum not called four times?
    n3=((n1=gnn( )) < (n2=gnn( )) ? (n1=gnn( ) : (n2=gnn( ))
    should be printed 4 times shouldn't it?

    • @ammartirmizi
      @ammartirmizi 2 года назад +3

      The ternary operator has one of the two outcomes after the "?". It depends on the initial expression. Thus, it is called thrice.

  • @bamberghh1691
    @bamberghh1691 2 года назад

    Isn't returning something from a block nonstandard?

    • @diceandbricks
      @diceandbricks 2 года назад

      Yes. Statement expressions are gcc extensions.

  • @ShadowlightSE
    @ShadowlightSE 2 года назад

    Do macros always return a value? I never see a "return" in macros.

    • @rmaster934
      @rmaster934 2 года назад +2

      They aren't technically a function, so no, they don't "return" anything. They just generate blocks of code that you specified.

    • @suncrafterspielt9479
      @suncrafterspielt9479 2 года назад +6

      Macros are basically just copy pasting, just like defines and includes. Thats also why we had this strange behaviour described in the video 6:50

  •  2 года назад

    I prefer using C++ with templates and const's instead of using defines. But everyone has a different preference.

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

    1:25 makefile

  • @aabdev
    @aabdev 2 года назад

    How to write a function that gets the variable and prints its name (as in code) in run time (without preprocessor)?
    int val_a=4;
    int val_b=5;
    print_name(val_a);
    print_name(val_b);
    Console:
    >val_a
    >val_b

    • @gaelfortier2668
      @gaelfortier2668 2 года назад +1

      You can't since variable names when compiled are lost. In machine binary, there is no variable name, only memory addresses and instructions

    • @gaelfortier2668
      @gaelfortier2668 2 года назад

      What the preprocessor does is it keeps a copy of the variable's name in the executable so that you can print it later.
      #define GET_VAR_NAME(var) #var
      This generates in your code a string litteral with the name of the variable "var".

  • @marusdod3685
    @marusdod3685 2 года назад +4

    macros can also kinda mimic generics, except you have to declare for every type combination ahead of time

    • @robertkiestov3734
      @robertkiestov3734 2 года назад +1

      >mask pfp
      Gross.

    • @marusdod3685
      @marusdod3685 2 года назад +1

      @@robertkiestov3734 I never wear a mask irl

    • @terrorist_nousagi8747
      @terrorist_nousagi8747 2 года назад

      @@robertkiestov3734 lol, what's gross about protecting yourself from germs?

    • @robertkiestov3734
      @robertkiestov3734 2 года назад

      @@terrorist_nousagi8747 Masks are zionistic propaganda that don’t work or do anything.

    • @terrorist_nousagi8747
      @terrorist_nousagi8747 2 года назад

      @@robertkiestov3734 Say that to Japan, wich is using masks way before the pandemic and has lower levels of contamination and slower growth of the pandemic

  • @easyelectronics4364
    @easyelectronics4364 2 года назад

    From where did you got so much of knowledge??? 😍

  • @user-om4cm9cu7j
    @user-om4cm9cu7j 2 года назад

    This is cool, just talk more stuff about function-like marcos!

  • @cmdlp4178
    @cmdlp4178 2 года назад +2

    Unfortunately compound expressions and typeof are not in the c standard.

    • @JacobSorber
      @JacobSorber  2 года назад +2

      Really?! I've never checked, but that's really sad. They're both really useful.

    • @cmdlp4178
      @cmdlp4178 2 года назад

      @@JacobSorber Both are very useful GNU Extensions that are widely supported. But good news: I have researched a little and found oth that since very recently the typeof operator might get into C23. The standart commitee should be made aware of all other extensions. Many of them have shown their potential in linux (eg. include/linux/math.h), here typeof, statement expressions and useful builtins are used. But there were the min and max operators in gcc, MIN(a, b) == a

    •  2 года назад

      you can kinda use C11's _GENERIC tho
      Edit: or in some cases you could use auto keyword/type

    • @kyrylmelekhin2667
      @kyrylmelekhin2667 2 года назад +1

      Or you can just make another macro parameter that will specify the type you want. Preprocessor will paste it in.

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

    shouldn't a modern day compiler eliminate the need for ifndef... and only include a header once.

  • @arielspalter7425
    @arielspalter7425 2 года назад

    The last example behaves like a template function.

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

    Compound statements are not part of the C standard, they are a compiler-specific extension.
    This is a problem for portability.

  • @sledgex9
    @sledgex9 2 года назад +3

    If in C++: Just use templates and gain type safety. Macros are hardly justified in modern C++ (at least most of the time).

  • @lef1970
    @lef1970 2 года назад +2

    This seems like bad practice to me - if it behaves like a function, shouldn’t it be a function?

  • @Aleksandar0100
    @Aleksandar0100 2 года назад +1

    >source code through patreon
    i thought the whole point of this channel is to help people learn C and computer science in general, putting the source behind a paywall contradicts that
    there are people who would still give you money regardless of you paywalling easy access to the code
    shame

    • @KarlKatten
      @KarlKatten 2 года назад +5

      It literally does not contradict it, you don't need the source code to understand what he is teaching. How much teaching do you do for free?

    • @JacobSorber
      @JacobSorber  2 года назад +4

      Thanks for the advice. You should think about creating your own channel. Then you can try out different approaches and run your channel in the way that makes the most sense to you.

    • @chaoticgoodcoding3700
      @chaoticgoodcoding3700 2 года назад

      If typing out what you see during a free video is the greatest difficulty you face when learning C then you should pleased.