Quote needed: Preprocessor usage is bad OO practice

后端 未结 14 1469
失恋的感觉
失恋的感觉 2020-12-09 04:29

I believe, that the usage of preprocessor directives like #if UsingNetwork is bad OO practice - other coworkers do not. I think, when using an IoC container (e.

相关标签:
14条回答
  • 2020-12-09 04:53

    In c# / VB.NET I would not say its evil.

    For example, when debugging windows services, I put the following in Main so that when in Debug mode, I can run the service as an application.

        <MTAThread()> _
        <System.Diagnostics.DebuggerNonUserCode()> _
        Shared Sub Main()
    
    
    #If DEBUG Then
    
            'Starts this up as an application.'
    
            Dim _service As New DispatchService()
            _service.ServiceStartupMethod(Nothing)
            System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite)
    
    #Else
    
            'Runs as a service. '
    
            Dim ServicesToRun() As System.ServiceProcess.ServiceBase
            ServicesToRun = New System.ServiceProcess.ServiceBase() {New DispatchService}
            System.ServiceProcess.ServiceBase.Run(ServicesToRun)
    
    #End If
    
        End Sub
    

    This is configuring the behavior of the application, and is certainly not evil. At the very least, its not as evil as trying to debug a service startup routine.

    Please correct me if I read your OP wrong, but it seems that you are complaining about others using a preprocessor when a simple boolean would suffice. If thats the case, dont damn the preprocessors, damn those using them in such fashion.

    EDIT: Re: first comment. I dont get how that example ties in here. The problem is that the preprocessor is being mis-used, not that it is evil.

    I'll give you another example. We have an application that does version checking between client and server on startup. In development, we often have different versions and dont want to do a version check. Is this evil?

    I guess what I am trying to say is that the preprocessor is not evil, even when changing program behavior. The problem is that someone is misusing it. What is wrong with saying that? Why are you trying to dismiss a language feature?

    Much later EDIT: FWIW: i haven't used preprocessor directives for this in a few years. I do use Environment.UserInteractive with a specific arg set ("-c" = Console), and a neat trick I picked up from somewhere here on SO to not block the application but still wait for user input.

    Shared Sub Main(args as string[])
      If (Environment.UserInteractive = True) Then
        'Starts this up as an application.
        If (args.Length > 0 AndAlso args[0].Equals("-c")) Then 'usually a "DeriveCommand" function that returns an enum or something similar
          Dim isRunning As Boolean = true
          Dim _service As New DispatchService()
          _service.ServiceStartupMethod(Nothing)
          Console.WriteLine("Press ESC to stop running")
          While (IsRunning)
            While (Not (Console.KeyAvailable AndAlso (Console.ReadKey(true).Key.Equals(ConsoleKey.Escape) OrElse Console.ReadKey(true).Key.Equals(ConsoleKey.R))))
               Thread.Sleep(1)
             End While                        
             Console.WriteLine()
             Console.WriteLine("Press ESC to continue running or any other key to continue shutdown.")
             Dim key = Console.ReadKey();
             if (key.Key.Equals(ConsoleKey.Escape))
             {
               Console.WriteLine("Press ESC to load shutdown menu.")
               Continue
             }
             isRunning = false
          End While
          _service.ServiceStopMethod()
        Else
          Throw New ArgumentException("Dont be a double clicker, this needs a console for reporting info and errors")
        End If
      Else
    
        'Runs as a service. '
        Dim ServicesToRun() As System.ServiceProcess.ServiceBase
        ServicesToRun = New System.ServiceProcess.ServiceBase() {New DispatchService}
        System.ServiceProcess.ServiceBase.Run(ServicesToRun)
      End If
    End Sub
    
    0 讨论(0)
  • 2020-12-09 04:53

    One quick point to tell your coworkers is this: the preprocessor breaks operator precedence in mathematical statements if symbols are used in such statements.

    0 讨论(0)
  • 2020-12-09 04:57

    IMHO, you talk about C and C++, not about OO practice in general. And C is not Object-oriented. In both languages the preprocessor is actually useful. Just use it correctly.

    I think this answer belongs to C++ FAQ: [29.8] Are you saying that the preprocessor is evil?.

    Yes, that's exactly what I'm saying: the preprocessor is evil.

    Every #define macro effectively creates a new keyword in every source file and every scope until that symbol is #undefd. The preprocessor lets you create a #define symbol that is always replaced independent of the {...} scope where that symbol appears.

    Sometimes we need the preprocessor, such as the #ifndef/#define wrapper within each header file, but it should be avoided when you can. "Evil" doesn't mean "never use." You will use evil things sometimes, particularly when they are "the lesser of two evils." But they're still evil :-)

    I hope this source is authoritative enough :-)

    0 讨论(0)
  • 2020-12-09 04:58

    Preprocessor code injection is to the compiler what triggers are to the database. And it's pretty easy to find such assertions about triggers.

    I mainly think of #define being used to inline a short expression because it saves the overhead of a function call. In other words, it's premature optimization.

    0 讨论(0)
  • 2020-12-09 04:58

    I wanted to ask a new question but looks like it fits here. I agree that having a full-blown preprocessor may be too much for Java. There is one clear need that is covered by precoprocessor in C world and not covered at all in Java world: I want debug printouts being completely ignored by compiler depending on debug level. Now we rely on "good practice" but in practice this practice is hard to enforce and still some redundant CPU load remains.

    In Java style that could be solved by having some designated methods like debug(), warning() etc. for which calls the code is generated conditionality.

    Actually that would be about a bit of integration of Log4J into the language.

    0 讨论(0)
  • 2020-12-09 05:02

    Henry Spencer wrote a paper called #ifdef Considered Harmful.

    Also, Bjarne Stroustrup himself, in the chapter 18 of his book The Design and Evolution of C++, frowns on the use of preprocessor and wishes to eliminate it completely. However, Stroustrup also recognizes the necessity for #ifdef directive and the conditional compilation and goes on to illustrate that there is no good alternative for it in C++.

    Finally, Pete Goodliffe, in chapter 13 of his book Code Craft: The Practice of Writing Excellent Code, gives an example how, even when used for its original purpose, #ifdef can make a mess out of your code.

    Hope this helps. However, if your co-workers won't listen to reasonable arguments in the first place, I doubt book quotes will help convince them ;)

    0 讨论(0)
提交回复
热议问题