Assign String to Number const lazarus / 62-General ---------------------------------------------------------------------- Okoba · 2023-10-07 09:29 Is there a way to assign a string to a number constant? I know I can do it by ConstTest1 way but I prefer an easier to write way like ConstTest2. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  ConstTest1: Word = Ord('X') + (Ord('Y') shl 8);  ConstTest2: Word = 'XY'; //! ---------------------------------------------------------------------- marcov · 2023-10-07 11:10 No, the only exception is fourcharcode in macpas mode I think. https://wiki.freepascal.org/User_Changes_2.2.0#MacPas_OSType.2FFourCha rCode ---------------------------------------------------------------------- Okoba · 2023-10-07 11:44 The best I could come up is this as FPC checks the length of the array and only allows it if they fit each other: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; const  ConstTest3: array[0..1] of Char = 'XY';  ConstTest4: array[0..2] of Char = 'XYZ';var  V: Word;begin  V := Word(ConstTest3); //Okay  V := Word(ConstTest4); //Errorend. ---------------------------------------------------------------------- Thaddy · 2023-10-07 14:18 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testxx;{$mode objfpc}{$J+}uses sysutils;begin  writeln('xyz'.ToInteger); // In mode {$J+} you can assign the value to any typed constend. ---------------------------------------------------------------------- Okoba · 2023-10-07 14:45 @Thaddy I need this for a const, and not a var. ---------------------------------------------------------------------- ASerge · 2023-10-07 17:32 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {$MODE OBJFPC}{$APPTYPE CONSOLE} const  CTest: record    case Byte of      0: (W: Word);      1: (A: array[0..1] of AnsiChar)  end = (A: 'XY'); begin  Writeln(CTest.W);  Readln;end. ---------------------------------------------------------------------- 440bx · 2023-10-07 20:25 very similar to ASerge's solution, you can also do this: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  StorageSpace : array[0..1] of char = 'XY'; { or, if you prefer, CharsAsChars }  CharsAsWord  : word absolute StorageSpace; ETA: I just remembered you mentioned you need this for a const and not a var.  The following does it for a const even though it does not look like it does: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i const  StorageSpace : array[0..1] of char = 'XY';var  CharsAsWord  : word absolute StorageSpace;The "var" isn't really a variable, it's a const (it is in read-only memory) ASerge's solution may be better because it isn't as potentially misleading as this one. HTH ---------------------------------------------------------------------- TRon · 2023-10-08 07:09 Quote from: Okoba on October 07, 2023, 11:29:11 amIs there a way to assign a string to a number constant? As marcov already wrote, no. With the addition: not for /true/ constants. The typed constant that you showed is not a constant in the traditional sense of the word (see also typed constants documentation, https://www.freepascal.org/docs- html/ref/refse10.html). And you can test that as well: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program test; const  x = word(12);  // this is a true constant, not a typed one though it is told to occupy a word (instead of a byte) var  y : array[0..1] of char absolute x;begin  y := 'x';  writeln('x = ', x);end.  Which will generate a beautiful runtime error 216 (as it should), see also https://www.freepascal.org/docs-html/user/userap4.html: Quote 216 General Protection fault     The application tried to access invalid memory space. This can be caused by several problems:     1.  Dereferencing a nil pointer.     2.  Trying to access memory which is out of bounds (for example, calling move with an invalid length). Rule 2 applies. Trying to write to memory that you are not allowed to (out of bounds). Ofc you can use the cast and shift method (together with ord) like you did to assign characters. It is a real PITA especially when you have to use many constants that are usually compared against using their number but actually contain ascii characters (for example some file formats do that). My vote would be to automatically make all type helpers intrinsincs so that Thaddy's solution can be used ---------------------------------------------------------------------- marcov · 2023-10-08 11:02 Quote from: jamie on October 07, 2023, 04:03:01 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  V := Word(PWord(@ConstTest4)^); Besides all other issues, this is not endianess safe. ---------------------------------------------------------------------- Thaddy · 2023-10-08 12:08 Quote from: Okoba on October 07, 2023, 04:45:12 pm@Thaddy I need this for a const, and not a var. You are using typed consts so this is a complete example of what you want, note I do not understand you could not figure out this yourself:Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testxx;{$mode objfpc}{$J+}uses sysutils;const a: integer =0;begin  a:= 'xyz'.toInteger;  writeln(a);end. ---------------------------------------------------------------------- ASerge · 2023-10-08 14:42 Quote from: Thaddy on October 08, 2023, 02:08:30 pmCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testxx;{$mode objfpc}{$J+}uses sysutils;const a: integer =0;begin  a:= 'xyz'.toInteger;  writeln(a);end. It's not even compiled. But if add {$H+}, there will still be an error converting 'xyz' to an integer. This is very much not what the topic starter wanted. ---------------------------------------------------------------------- bytebites · 2023-10-08 16:14 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program testxx;{$mode objfpc}{$J+}{$MODESWITCH TYPEHELPERS}{$H+}uses sysutils;const a: integer =0; type tstrhlp=type helper for string   function toInteger:integer;end; function tstrhlp.toInteger: integer;begin  result:=pword(pchar(self))^;end; begin  a:= 'xyz'.toInteger;end. ---------------------------------------------------------------------- Curt Carpenter · 2023-10-08 18:51 The whole thing looks like a bit of an abomination against the strong typing philosophy of the Pascal language to me.  You're packing characters into a word here, and I would vote for one of the explicit forms of doing that (as presented in the original post and elsewhere here). Even though it's a pain for the writer, it's a kindness to a future reader.  As Cantu notes in his Object Pascal Handbook:  QuoteDirect type casting is a dangerous programming practice, because it allows you to access a value as if it represented something else. Since the internal representations of data types generally do not match (and might even change depending on the target platform), you risk accidentally creating hard-to-track errors. For this reason, you should generally avoid type casting.  Accessing a value as if it is something else is more of a problem for a future reader, in my view, than it is for the writer. ---------------------------------------------------------------------- 440bx · 2023-10-08 19:08 Quote from: Curt Carpenter on October 08, 2023, 08:51:29 pmThe whole thing looks like a bit of an abomination against the strong typing philosophy of the Pascal language to me.  You're packing characters into a word here, and I would vote for one of the explicit forms of doing that (as presented in the original post and elsewhere here). Even though it's a pain for the writer, it's a kindness to a future reader.  That's a very valid concern BUT, there are some cases, really few, where it is very convenient to interpret numbers as character strings or viceversa. One case that comes to mind is specifying the MS-DOS signature header "MZ", it's really convenient to tell the compiler "the binary word resulting from the characters "MZ".  To generalize, it is usually convenient to specify signatures of some sort as a string of characters (2, 4, 8 characters) even though they are stored as numbers for efficiency/performance reasons (not to mention that it saves some coding.)  It's quite common to see that in C /C++ code and it's a bit unfortunate that Pascal does not allow doing it in a straightforward way. ---------------------------------------------------------------------- Curt Carpenter · 2023-10-08 21:34 I understand.  But in the limit I guess  one could argue that it's unfortunate that Pascal isn't C/C++ (or vice versa, depending on one's religion). ---------------------------------------------------------------------- TRon · 2023-10-08 21:45 Quote from: Curt Carpenter on October 08, 2023, 11:34:26 pmI understand.  But in the limit I guess  one could argue that it's unfortunate that Pascal isn't C/C++ (or vice versa, depending on one's religion).    It is just that c solves that with pre-processor junk and which is lacking in/for Pascal (though a 3th party pre-processor for pascal is possible to use, see also the plugin request that was recently made in another thread)). The stand on preprocessing for FPC is clear: it will not be added and existing macro language (if you can call it that) will not be extended. That has both a down and an upside. Upside being that in c it is sometime impossible to see/determine what (source)code is actually being generated because of the excess use of preprocessing scripts the downside being that sometimes in FPC you need to get your hands (pretty) dirty to try and achieve the same results. ---------------------------------------------------------------------- PascalDragon · 2023-10-10 19:21 Quote from: TRon on October 08, 2023, 11:45:46 pmQuote from: Curt Carpenter on October 08, 2023, 11:34:26 pmI understand.  But in the limit I guess  one could argue that it's unfortunate that Pascal isn't C/C++ (or vice versa, depending on one's religion).    It is just that c solves that with pre-processor junk and which is lacking in/for Pascal (though a 3th party pre-processor for pascal is possible to use, see also the plugin request that was recently made in another thread)). It's not the preprocessor, but that in C and C++ the (unsigned) char type is also a numeric type and used as the equivalent to Pascal's Byte and ShortInt, thus one can simply assign sequences of characters to numeric types. In Pascal this does not fit with the type system. ---------------------------------------------------------------------- TRon · 2023-10-11 04:42 Quote from: PascalDragon on October 10, 2023, 09:21:59 pmIt's not the preprocessor, but that in C and C++ the (unsigned) char type is also a numeric type and used as the equivalent to Pascal's Byte and ShortInt, thus one can simply assign sequences of characters to numeric types. In Pascal this does not fit with the type system. True so no point in arguing against that  I referred to one step further down the line. Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #define MAKE_ID(a,b,c,d)        \        ((ULONG) (a)<<24 | (ULONG) (b)<<16 | (ULONG) (c)<<8 | (ULONG) (d))  and for usage example Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #define IFFLCI_PROP         MAKE_ID('p','r','o','p')  Which, in theory, could be solved using macros just as the c counterpart shown here. ---------------------------------------------------------------------- Zoran · 2023-10-11 16:39 This works: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; {$mode objfpc}{$H+}{$J-} uses SysUtils; const  ConstS: array[0..1] of char = 'XY';  //ConstS: AnsiString = 'XY'; // this also works var // although under var section, this is a constant.  ConstW: Word absolute ConstS;  // Just keep in mind that byte order depends on architecture! begin                                                                           // ConstW := 4;  // compiler error in {$J-}. So, although declared                   // in var section, it's really (typed) constant.   WriteLn('const word: ', ConstW, ' (hex: $', ConstW.ToHexString(2), ')');  ReadLn;end.  Although this works when you declare ConstS as AnsiString instead of fixed-length char array, I'd rather avoid using a managed type for this purpose. And keep in mind that when compiled on different endian system, you will get different value (the byte order in Word will be swapped)!