diff --git a/CHANGELOG b/CHANGELOG
index 9667715cf24a4e35175dbf19f6f63462f5fe2a24..ce293a99f23c1c22ee2641128a9a4e6c581e3b05 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+0.5.2 (12/31/2009):
+-------------------
+
+- Modified partition creation function to begin partitions on 8-sector
+  boundaries by default. This improves performance on the new Western
+  Digital Advanced Format drives. The new 'd' and 'l' options on the
+  experts' menu display and change, respectively, the boundary size.
+
+- Tweaked code to produce fewer warnings on the latest versions of
+  GCC.
+
 0.5.1:
 ------
 
diff --git a/gdisk.8 b/gdisk.8
index 6c87d0f4f8a7271f51b74f087a1f69d78b783233..f65ec7ec847f9f91e9e66262269e93cc52203203 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
 .\" Copyright 2009 Roderick W. Smith (rodsmith@rodsbooks.com)
 .\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.5.0" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.5.1" "Roderick W. Smith" "GPT fdisk Manual"
 .SH "NAME"
 gdisk \- GUID partition table (GPT) manipulator for Linux and Unix
 .SH "SYNOPSIS"
@@ -416,12 +416,20 @@ you might want to adjust the number manually if you've wound up with the
 same GUID on two partitions because of buggy GUID assignments (hopefully
 not in \fBgdisk\fR) or sheer incredible coincidence.
 
+.TP
+.B d
+Display the number of logical sectors per physical sector. This value
+determines the sector alignment that GPT fdisk enforces. See the
+description of the 'l' option for more details. Note that this value
+is not actually detected on a disk-by-disk basis; it's set to 8 as a
+blanket default.
+
 .TP
 .B e
-Relocate backup GPT data structures. Use this command if you've added
-disks to a RAID array, thus creating a virtual disk with space that follows
-the backup GPT data structures. This command moves the backup GPT data
-structures to the end of the disk, where they belong.
+Move backup GPT data structures to the end of the disk. Use this command if
+you've added disks to a RAID array, thus creating a virtual disk with space
+that follows the backup GPT data structures. This command moves the backup
+GPT data structures to the end of the disk, where they belong.
 
 .TP 
 .B g
@@ -434,6 +442,22 @@ a fresh random GUID or enter one manually with this option.
 Show detailed partition information. This option is identical to the 'i'
 option on the main menu.
 
+.TP
+.B l
+Change the number of logical sectors per physical sector. Prior to December
+of 2009, most hard disks used 512-byte physical sectors. Starting in
+December of 2009, disk manufacturers began transitioning to disks with
+larger physical sectors, but their firmware translated to 512-byte logical
+sectors to maintain compatibility with older OSes. If partitions begin
+mid-physical-sector, though, performance can suffer on such drives, since
+important filesystem data structures can span physical sectors on the disk.
+To minimize such problems, GPT fdisk aligns the start of partitions on the
+boundary of presumed physical sectors. You can set the number of logical
+sectors per physical sector with this option. The default is 8, which is
+set blindly; GPT fdisk does not currently read this information from the
+disk. The default value will result in a tiny amount of wasted disk space
+on older disks with true 512-byte sectors but will otherwise be harmless.
+
 .TP 
 .B m
 Return to the main menu. This option enables you to enter main\-menu commands.
@@ -501,7 +525,7 @@ entering data. When only one option is possible, \fBgdisk\fR
 usually bypasses the prompt entirely.
 
 .SH "BUGS"
-As of September 2009 (version 0.5.0), \fBgdisk\fR
+As of November 2009 (version 0.5.1), \fBgdisk\fR
 should be considered beta software. Known bugs and limitations include:
 
 .TP 
diff --git a/gdisk.cc b/gdisk.cc
index bfee217af7f89bfde9198453894cfff46ff92081..3414d89d052a8e7f138738def3222e988aaf8fe2 100644
--- a/gdisk.cc
+++ b/gdisk.cc
@@ -29,7 +29,7 @@ int main(int argc, char* argv[]) {
    int doMore = 1;
    char* device = NULL;
 
-   printf("GPT fdisk (gdisk) version 0.5.1-pre3\n\n");
+   printf("GPT fdisk (gdisk) version 0.5.2\n\n");
 
     if (argc == 2) { // basic usage
       if (SizesOK()) {
@@ -309,6 +309,10 @@ void ExpertsMenu(char* filename, struct GPTData* theGPT) {
                theGPT->SetPartitionGUID(pn, GetGUID());
             } else printf("No partitions\n");
             break;
+         case 'd': case 'D':
+            printf("The number of logical sectors per physical sector is set to %d.\n",
+                   theGPT->GetAlignment());
+            break;
          case 'e': case 'E':
             printf("Relocating backup data structures to the end of the disk\n");
             theGPT->MoveSecondHeaderToEnd();
@@ -320,6 +324,10 @@ void ExpertsMenu(char* filename, struct GPTData* theGPT) {
          case 'i': case 'I':
             theGPT->ShowDetails();
             break;
+         case 'l': case 'L':
+            temp1 = GetNumber(1, 128, 8, "Enter the number of logical sectors in a physical sector on the\ndisk (1-128, default = 8): ");
+            theGPT->SetAlignment(temp1);
+            break;
          case 'm': case 'M':
             MainMenu(filename, theGPT);
             goOn = 0;
@@ -366,9 +374,11 @@ void ExpertsMenu(char* filename, struct GPTData* theGPT) {
 void ShowExpertCommands(void) {
    printf("a\tset attributes\n");
    printf("c\tchange partition GUID\n");
+   printf("d\tdisplay the number of logical sectors per physical sector\n");
    printf("e\trelocate backup data structures to the end of the disk\n");
    printf("g\tchange disk GUID\n");
    printf("i\tshow detailed information on a partition\n");
+   printf("b\tset the number of logical sectors per physical sector\n");
    printf("m\treturn to main menu\n");
    printf("n\tcreate a new protective MBR\n");
    printf("o\tprint protective MBR data\n");
diff --git a/gpt.cc b/gpt.cc
index 2e997143bb90d54ae3eec1c5c5ed9bdb1904ccb3..c34c8623ef50647e1df73523007267e3cc030ddf 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -46,6 +46,7 @@ GPTData::GPTData(void) {
    secondPartsCrcOk = 0;
    apmFound = 0;
    bsdFound = 0;
+   sectorAlignment = 8; // Align partitions on 4096-byte boundaries by default
    srand((unsigned int) time(NULL));
    SetGPTSize(NUM_GPT_ENTRIES);
 } // GPTData default constructor
@@ -63,6 +64,7 @@ GPTData::GPTData(char* filename) {
    secondPartsCrcOk = 0;
    apmFound = 0;
    bsdFound = 0;
+   sectorAlignment = 8; // Align partitions on 4096-byte boundaries by default
    srand((unsigned int) time(NULL));
    LoadPartitions(filename);
 } // GPTData(char* filename) constructor
@@ -83,8 +85,8 @@ GPTData::~GPTData(void) {
 // do *NOT* recover from these problems. Returns the total number of
 // problems identified.
 int GPTData::Verify(void) {
-   int problems = 0, numSegments;
-   uint64_t totalFree, largestSegment;
+   int problems = 0, numSegments, i;
+   uint64_t totalFree, largestSegment, firstSector;
    char tempStr[255], siTotal[255], siLargest[255];
 
    // First, check for CRC errors in the GPT data....
@@ -199,6 +201,16 @@ int GPTData::Verify(void) {
    // Verify that partitions don't run into GPT data areas....
    problems += CheckGPTSize();
 
+   // Check that partitions are aligned on proper boundaries (for WD Advanced
+   // Format and similar disks)....
+   for (i = 0; i < mainHeader.numParts; i++) {
+      if ((partitions[i].GetFirstLBA() % sectorAlignment) != 0) {
+         printf("\nCaution: Partition %d doesn't begin on a %d-sector boundary. This may\n"
+                "result in degraded performance on some modern (2010 and later) hard disks.\n",
+                i + 1, sectorAlignment);
+      } // if
+   } // for
+
    // Now compute available space, but only if no problems found, since
    // problems could affect the results
    if (problems == 0) {
@@ -726,7 +738,7 @@ void GPTData::LoadSecondTableAsMain(void) {
          printf("Error! Couldn't seek to backup partition table!\n");
       } // if/else
    } else {
-      printf("Error! Couldn't open device %s when recovering backup partition table!\n");
+      printf("Error! Couldn't open device %s when recovering backup partition table!\n", device);
    } // if/else
 } // GPTData::LoadSecondTableAsMain()
 
@@ -755,7 +767,7 @@ int GPTData::SaveGPTData(void) {
    if (mainHeader.backupLBA > diskSize) {
       fprintf(stderr, "Error! Disk is too small! The 'e' option on the experts' menu might fix the\n"
               "problem (or it might not). Aborting!\n");
-      printf("(Disk size is %ld sectors, needs to be %ld sectors.)\n", diskSize,
+      printf("(Disk size is %llu sectors, needs to be %llu sectors.)\n", diskSize,
              mainHeader.backupLBA);
       allOK = 0;
    } // if
@@ -1183,6 +1195,7 @@ void GPTData::CreatePartition(void) {
       do {
          sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, prompt);
       } while (IsFree(sector) == 0);
+      Align(&sector); // Align sector to correct multiple
       firstBlock = sector;
 
       // Get last block for new partitions...
@@ -1315,7 +1328,7 @@ int GPTData::DestroyGPT(int prompt) {
          printf("GPT data structures destroyed! You may now partition the disk using fdisk or\n"
                "other utilities. Program will now terminate.\n");
       } else {
-         printf("Problem opening %s for writing! Program will now terminate.\n");
+         printf("Problem opening %s for writing! Program will now terminate.\n", device);
       } // if/else (fd != -1)
    } // if (goOn == 'Y')
    return (goOn == 'Y');
@@ -1885,6 +1898,71 @@ int GPTData::SetPartitionGUID(uint32_t pn, GUIDData theGUID) {
    return retval;
 } // GPTData::SetPartitionGUID()
 
+// Adjust sector number so that it falls on a sector boundary that's a
+// multiple of sectorAlignment. This is done to improve the performance
+// of Western Digital Advanced Format disks and disks with similar
+// technology from other companies, which use 4096-byte sectors
+// internally although they translate to 512-byte sectors for the
+// benefit of the OS. If partitions aren't properly aligned on these
+// disks, some filesystem data structures can span multiple physical
+// sectors, degrading performance. This function should be called
+// only on the FIRST sector of the partition, not the last!
+// This function returns 1 if the alignment was altered, 0 if it
+// was unchanged.
+int GPTData::Align(uint64_t* sector) {
+   int retval = 0, sectorOK = 0;
+   uint64_t earlier, later, testSector, original;
+
+   if ((*sector % sectorAlignment) != 0) {
+      original = *sector;
+      retval = 1;
+      earlier = (*sector / sectorAlignment) * sectorAlignment;
+      later = earlier + (uint64_t) sectorAlignment;
+
+      // Check to see that every sector between the earlier one and the
+      // requested one is clear, and that it's not too early....
+      if (earlier >= mainHeader.firstUsableLBA) {
+//         printf("earlier is %llu, first usable is %llu\n", earlier, mainHeader.firstUsableLBA);
+         sectorOK = 1;
+         testSector = earlier;
+         do {
+            sectorOK = IsFree(testSector++);
+         } while ((sectorOK == 1) && (testSector < *sector));
+         if (sectorOK == 1) {
+            *sector = earlier;
+//            printf("Moved sector earlier.\n");
+         } // if
+      } // if firstUsableLBA check
+
+      // If couldn't move the sector earlier, try to move it later instead....
+      if ((sectorOK != 1) && (later <= mainHeader.lastUsableLBA)) {
+         sectorOK = 1;
+         testSector = later;
+         do {
+            sectorOK = IsFree(testSector--);
+         } while ((sectorOK == 1) && (testSector > *sector));
+         if (sectorOK == 1) {
+            *sector = later;
+//            printf("Moved sector later\n");
+         } // if
+      } // if
+
+      // If sector was changed successfully, inform the user of this fact.
+      // Otherwise, notify the user that it couldn't be done....
+      if (sectorOK == 1) {
+         printf("Information: Moved requested sector from %llu to %llu for\n"
+               "alignment purposes. Use 'l' on the experts' menu to adjust alignment.\n",
+               original, *sector);
+      } else {
+         printf("Information: Sector not aligned on %d-sector boundary and could not be moved.\n"
+                "If you're using a Western Digital Advanced Format or similar disk with\n"
+                "underlying 4096-byte sectors, performance may suffer.\n", sectorAlignment);
+         retval = 0;
+      } // if/else
+   } // if
+   return retval;
+} // GPTData::Align()
+
 /********************************************************
  *                                                      *
  * Functions that return data about GPT data structures *
@@ -2141,35 +2219,35 @@ int SizesOK(void) {
    int allOK = 1;
 
    if (sizeof(uint8_t) != 1) {
-      fprintf(stderr, "uint8_t is %d bytes, should be 1 byte; aborting!\n", sizeof(uint8_t));
+      fprintf(stderr, "uint8_t is %lu bytes, should be 1 byte; aborting!\n", sizeof(uint8_t));
       allOK = 0;
    } // if
    if (sizeof(uint16_t) != 2) {
-      fprintf(stderr, "uint16_t is %d bytes, should be 2 bytes; aborting!\n", sizeof(uint16_t));
+      fprintf(stderr, "uint16_t is %lu bytes, should be 2 bytes; aborting!\n", sizeof(uint16_t));
       allOK = 0;
    } // if
    if (sizeof(uint32_t) != 4) {
-      fprintf(stderr, "uint32_t is %d bytes, should be 4 bytes; aborting!\n", sizeof(uint32_t));
+      fprintf(stderr, "uint32_t is %lu bytes, should be 4 bytes; aborting!\n", sizeof(uint32_t));
       allOK = 0;
    } // if
    if (sizeof(uint64_t) != 8) {
-      fprintf(stderr, "uint64_t is %d bytes, should be 8 bytes; aborting!\n", sizeof(uint64_t));
+      fprintf(stderr, "uint64_t is %lu bytes, should be 8 bytes; aborting!\n", sizeof(uint64_t));
       allOK = 0;
    } // if
    if (sizeof(struct MBRRecord) != 16) {
-      fprintf(stderr, "MBRRecord is %d bytes, should be 16 bytes; aborting!\n", sizeof(MBRRecord));
+      fprintf(stderr, "MBRRecord is %lu bytes, should be 16 bytes; aborting!\n", sizeof(MBRRecord));
       allOK = 0;
    } // if
    if (sizeof(struct TempMBR) != 512) {
-      fprintf(stderr, "TempMBR is %d bytes, should be 512 bytes; aborting!\n", sizeof(TempMBR));
+      fprintf(stderr, "TempMBR is %lu bytes, should be 512 bytes; aborting!\n", sizeof(TempMBR));
       allOK = 0;
    } // if
    if (sizeof(struct GPTHeader) != 512) {
-      fprintf(stderr, "GPTHeader is %d bytes, should be 512 bytes; aborting!\n", sizeof(GPTHeader));
+      fprintf(stderr, "GPTHeader is %lu bytes, should be 512 bytes; aborting!\n", sizeof(GPTHeader));
       allOK = 0;
    } // if
    if (sizeof(GPTPart) != 128) {
-      fprintf(stderr, "GPTPart is %d bytes, should be 128 bytes; aborting!\n", sizeof(GPTPart));
+      fprintf(stderr, "GPTPart is %lu bytes, should be 128 bytes; aborting!\n", sizeof(GPTPart));
       allOK = 0;
    } // if
 // Determine endianness; set allOK = 0 if running on big-endian hardware
diff --git a/gpt.h b/gpt.h
index f22bd61dfc7998c37160447a70f3b6581a432955..c0bf53c6b419e158c7689b5202c2e7dccc470445 100644
--- a/gpt.h
+++ b/gpt.h
@@ -67,6 +67,7 @@ protected:
    int secondPartsCrcOk;
    int apmFound; // set to 1 if APM detected
    int bsdFound; // set to 1 if BSD disklabel detected in MBR
+   int sectorAlignment; // Start & end partitions at multiples of sectorAlignment
    PartTypes typeHelper;
 public:
    // Basic necessary functions....
@@ -132,6 +133,8 @@ public:
    void SetDiskGUID(GUIDData newGUID);
    int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
    void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();}
+   int Align(uint64_t* sector);
+   void SetAlignment(int n) {sectorAlignment = n;}
 
    // Return data about the GPT structures....
    int GetPartRange(uint32_t* low, uint32_t* high);
@@ -143,7 +146,7 @@ public:
    uint64_t GetBlocksInPartTable(void) {return (mainHeader.numParts *
                    mainHeader.sizeOfPartitionEntries) / blockSize;}
    uint32_t CountParts(void);
-
+   int GetAlignment(void) {return sectorAlignment;}
 
    // Find information about free space
    uint64_t FindFirstAvailable(uint64_t start = 0);
diff --git a/support.cc b/support.cc
index bb419ed537877d56697ba2cb8bd548de3fae6b85..090261784a168c1a0456c221032d147cd3887591 100644
--- a/support.cc
+++ b/support.cc
@@ -34,7 +34,7 @@ int GetNumber(int low, int high, int def, const char prompt[]) {
    if (low != high) { // bother only if low and high differ...
       response = low - 1; // force one loop by setting response outside range
       while ((response < low) || (response > high)) {
-         printf(prompt);
+         printf("%s", prompt);
          fgets(line, 255, stdin);
          num = sscanf(line, "%d", &response);
          if (num == 1) { // user provided a response
@@ -83,7 +83,7 @@ uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, char prompt[])
 
    response = low - 1; // Ensure one pass by setting a too-low initial value
    while ((response < low) || (response > high)) {
-      printf(prompt);
+      printf("%s", prompt);
       fgets(line, 255, stdin);
 
       // Remove leading spaces, if present