There is a set of constants representing offsets in some file. These offsets are fixed. And they range from 0 to 0x1FFFFFF. How to present them in the most convenient way in the source code? The code will be with classes. And, accordingly, the namespace also does not want to clutter up.

Options to choose from:

  1. Macros using define . Bad that no words.
  2. const in the right quantity. It is possible inside some separate namespace - well, but it seems rather dreary to type them in the right amount.
  3. enum . The problem here is that the constants will not go in a row. And again, it turns out not very convenient.

Of course, you can still make a structure with alignment = 1 and stuff the necessary number of variables and arrays inside it. But this is not the PLO at all. And what will happen if the file format changes (a tail is added)? Ugly shorter.

What did I forget or miss?

  • Can you look for a method for calculating offsets (or store them in the header of the file itself) and generally get rid of constants in this way? Hard coding offsets on the move seems like a bad idea. - igumnov
  • Um ... there is no method for calculating offsets Here they are and the point. > Hard coding offsets on the move seems like a bad idea Questions to the comrades who developed the file format. IMHO. In fact, it is quite convenient, because each version has a fixed size. But there are several versions. And will have to support each. The format is naturally binary. There would be a text - it would be even worse =) - gecube
  • @gecube, so you are supposed to work the same program with multiple formats? Then, as far as I understand, the same constant name can, depending on the format, give different offsets. In this case, I do not think that the @Kotik_hohet_kusat option would be convenient for programming. Perhaps the best option would be an array (the size of the number of formats) structures with the same field names . Filling in these fields with offset values ​​is, of course, a separate song, but access to data on such offsets (of course, indirect) will be convenient. - avp
  • In the best traditions of OOP, each format will have its own loader class in a separate file, so there is no problem - gecube
  • @gecube, very often the result of "the best traditions of OOP" is so many words that the essence of the program sinks into them. The simpler, the better (but not simpler than necessary). - avp

4 answers 4

It seems to me a reasonable option with constants in unnamed namespace. I will try to argue:

  • The values ​​of some kind of file offset' s are implementation details, so there is no need to provide some kind of access to them from the outside.

  • If for some reason several different classes should have access to these constants, then you can use a named namespace like detail or change the code so that the use of constants is localized in one of them. The second option in this case seems preferable.

  • Such a solution is better than enum, because ideologically enum serves for a named representation of some set of unique values. If we are talking about the offset' s in the file, then you most likely do not have a strict guarantee of this very uniqueness, so using enum can confuse the future reader of the code.

  • Not very clear is your phrase about the “dreary typing”. Code of the form const unsigned int kInitialFileOffset = 25 subjectively does not look too complicated to set :)

  • If you look at the source code of more or less well-known projects, for example, the authors of Chromium use exactly this approach:

     namespace { // If the remaining session time falls below this threshold, the user should be // informed that the session is about to expire. const int kExpiringSoonThresholdInSeconds = 5 * 60; // 5 minutes. // Color in which the remaining session time is normally shown. const SkColor kRemainingTimeColor = SK_ColorWHITE; // Color in which the remaining session time is shown when it is expiring soon. const SkColor kRemainingTimeExpiringSoonColor = SK_ColorRED; 
  • Yes, I like it. Zdorovski. do we have a namespace to limit the visibility of constants to the current file? > subjectively, it doesn’t look too difficult for recruitment. Well, in principle, yes, copy-paste-yes, not very hard. - gecube
  • one
    I corrected the answer a little - in the previous version the simultaneous use of unnamed namespace and static const was superfluous:> [7.3.1.1] provides a superior alternative. [7.3.1.1 / Note 82] can be seen. - Costantino Rupert
  • In general, the answer @ Kotik_hohet_kushat I liked the most. The solution is really neat and functional. - gecube

I am in favor of the structure. True, it is not obligatory to make one large, but to break it into logical components. These structures may be private members of the class.

But this is not the PLO at all.

Do you think there are 100,500 lines that are difficult to understand, a lot of constants or 2-3 reading structures. And also the speed ... I think this is a normal OOP.

And what will happen if the file format changes (a tail is added)?

Will your file change regularly? badly. But if the reading is divided into several logical structures, then simply either replace one or add one more. And all business.

  • The fact is that with the structure such a nuance creeps in, that the format is not mine and I am interested in quite specific areas of the file. Let's say a little in the beginning, a little in the end, a bit in the middle. All that between - for me, in fact, garbage. The file is quite large. Let's say ~ 10MB. Therefore, it will be problematic to completely suck it into the structure. Yes, and not necessary. - gecube
  • The main thing is that then it would not become clear that these values ​​are needed. But you need to look in more detail, maybe there are two or three areas where you need to read the data - under them there will be local structures. - KoVadim

In general, constants defined elsewhere or scattered across the namespace (which is even worse) are bad style. You might have stumbled upon this article . See the fifth paragraph, in which it is recommended to replace the constants with functions that return a certain static value. Functions, of course, can be logically combined into a class or structure, and even make them static (in a logical space). For example, the definition:

 MAX_ITERATIONS = 25 

Can be replaced by:

 int getMaxIterations() { return 25; } 
  • The article, of course, read. Glad you saw her too. In my opinion, the theses stated in it are very controversial. But to think it is undoubtedly useful. For trying to answer thanks. Functions I don't like. They are not visible semantics of constancy. Tomorrow Uncle Vasya will come and return a link to something. In my opinion, the constant should be constant. Moreover, the compiler may eventually optimize it. On the other hand, I saw the approach you indicated in a couple of projects, but he was really justified there. Moreover, these were member functions that were redefined in the descendant class. - gecube
  • @gecube, functions instead of constants are not cute to me either. But the reasoning about who will come tomorrow ... How many people do you have the whole project doing? And what about the module (I mean NOT the compilation unit) with the processing of file formats? - avp

I would use enum, which can also be a private member of a class. Expanding enum will not be difficult in my opinion, for example:

 enum Offset { Field1 = 0x00000003, Field2 = 0x0000000a, Reserved = Field2+1 }; 

This practice is common, for example in the Qt library.